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 2016/03/11 14:45:49 UTC

[01/13] syncope git commit: [SYNCOPE-771] Rename completed

Repository: syncope
Updated Branches:
  refs/heads/master 40288e97c -> 61a7fdd38


http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
index b67ae4e..60bb75b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
@@ -230,13 +230,13 @@ public class VirAttrITCase extends AbstractITCase {
         JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 
         String value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+                "SELECT USERNAME FROM testpull WHERE ID=?", String.class, actual.getKey());
         assertEquals("virattrcache", value);
 
-        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
+        jdbcTemplate.update("UPDATE testpull set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
 
         value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+                "SELECT USERNAME FROM testpull WHERE ID=?", String.class, actual.getKey());
         assertEquals("virattrcache2", value);
 
         // 4. check for cached attribute value
@@ -393,13 +393,13 @@ public class VirAttrITCase extends AbstractITCase {
         JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 
         String value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+                "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO.getKey());
         assertEquals("virattrcache", value);
 
-        jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", userTO.getKey());
+        jdbcTemplate.update("UPDATE testpull set USERNAME='virattrcache2' WHERE ID=?", userTO.getKey());
 
         value = jdbcTemplate.queryForObject(
-                "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+                "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO.getKey());
         assertEquals("virattrcache2", value);
         // ----------------------------------------
 
@@ -557,7 +557,7 @@ public class VirAttrITCase extends AbstractITCase {
             JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 
             Map<String, Object> actuals = jdbcTemplate.queryForMap(
-                    "SELECT id, surname, email FROM testsync WHERE id=?",
+                    "SELECT id, surname, email FROM testpull WHERE id=?",
                     new Object[] { Integer.parseInt(userTO.getPlainAttrMap().get("aLong").getValues().get(0)) });
 
             assertEquals(userTO.getPlainAttrMap().get("aLong").getValues().get(0), actuals.get("id").toString());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/concepts/concepts.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/concepts/concepts.adoc b/src/main/asciidoc/concepts/concepts.adoc
index c781e50..2e63820 100644
--- a/src/main/asciidoc/concepts/concepts.adoc
+++ b/src/main/asciidoc/concepts/concepts.adoc
@@ -42,7 +42,7 @@ include::provisioning/provisioning.adoc[]
 
 ==== Push
 
-==== Synchronization
+==== Pull
 
 === Workflow and Approval
 
@@ -52,4 +52,4 @@ include::provisioning/provisioning.adoc[]
 
 === Audit
 
-=== Delegated Administration
\ No newline at end of file
+=== Delegated Administration

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/concepts/provisioning/provisioning.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/concepts/provisioning/provisioning.adoc b/src/main/asciidoc/concepts/provisioning/provisioning.adoc
index 35f5987..8a623e1 100644
--- a/src/main/asciidoc/concepts/provisioning/provisioning.adoc
+++ b/src/main/asciidoc/concepts/provisioning/provisioning.adoc
@@ -22,8 +22,8 @@ User and role provisioning refers to the creation, maintenance, activation and d
 and their attributes. Provisioning operations can act on Apache Syncope only or be propagated towards external 
 resources as well.
 The provisioning operation can be initiated by an authorized user (for instance, working on Apache Syncope 
-administration console) or by an internal task like a synchronization task.
-A synchronization task can be used to perform a bulk provisioning operation involving either Syncope and one 
+administration console) or by an internal task like a pull task.
+A push task can be used to perform a bulk provisioning operation involving either Syncope and one 
 or more external resources.
 
 include::connectors.adoc[]
@@ -34,4 +34,4 @@ include::propagation.adoc[]
 
 include::push.adoc[]
 
-include::sync.adoc[]
\ No newline at end of file
+include::pull.adoc[]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/concepts/provisioning/pull.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/concepts/provisioning/pull.adoc b/src/main/asciidoc/concepts/provisioning/pull.adoc
new file mode 100644
index 0000000..bf2157a
--- /dev/null
+++ b/src/main/asciidoc/concepts/provisioning/pull.adoc
@@ -0,0 +1,52 @@
+//
+// 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.
+//
+==== Pull
+Basically, pull is the mechanism used by Apache Syncope to acquire user, group and any objects data from external resources.
+Pull can be "full" (full reconciliation) or "incremental".
+In the former case, each pull task execution will take over just of changes from the previous execution 
+(if exists and connector permits incremental pull).
+In the latter case, each pull task execution will take over of the entire set of data managed by the external resource.
+
+===== From an external resource to Syncope
+All the entity (user/group) data involved by a pull are retrieved from an external resource and processed 
+internally by Syncope itself.
+A retrieved entity can be:
+
+. a matching entity, if a corresponding local/internal entity has been found;
+. or an unmatching entity, otherwise.
+
+By default, Syncope will create locally all the unmatching entities (without linking entities and resources) and will 
+update all the matching ones.
+By the way, a different behaviour can be configured working with matching/unmatching rules.
+
+===== Matching and Unmatching rules
+Unmatching (corresponding user not found on Syncope):
+
+* IGNORE / UNLINK (do not perform any action);
+* ASSIGN (create entity linking the resource);
+* PROVISION (create entity without linking the resource).
+
+Matching (corresponding users found on Syncope):
+
+* IGNORE (do not perform any action);
+* UPDATE (update matching entity);
+* DEPROVISION (delete resource entity);
+* UNASSIGN (unlink resource and delete resource entity) ;
+* UNLINK (just unlink resource without performing any (de-)provisioning operation);
+* LINK (just link resource without performing any (de-)provisioning operation).
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/concepts/provisioning/resources.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/concepts/provisioning/resources.adoc b/src/main/asciidoc/concepts/provisioning/resources.adoc
index b9b7070..03c78af 100644
--- a/src/main/asciidoc/concepts/provisioning/resources.adoc
+++ b/src/main/asciidoc/concepts/provisioning/resources.adoc
@@ -32,7 +32,7 @@ to that resource.
 Users and roles can be assigned to an external resource by defining a direct or indirect link between objects.
 By the way, Apache Syncope empowers the possibility to control the existence of users/roles on external resources 
 giving the possibility to manage remote provisioning directly.
-In fact, an authorized user (or an internal task - a sync task, for instance) can ask for 
+In fact, an authorized user (or an internal task - a pull task, for instance) can ask for 
 
 * *link / unlink* users/roles to/from specific resources (soft link), 
 * *assign / unassign* users/roles to/from specific resources (hard link),
@@ -48,4 +48,4 @@ of reclaims.
 Assign/Unassign::
 Apache Syncope gives the possibility to create and remove a sort of hard linking between users/roles and resources.
 This kind of link implies propagation at link creation/deletion time: it is the composition between link/unlink and 
-provision/de-provision operations.
\ No newline at end of file
+provision/de-provision operations.

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/concepts/provisioning/sync.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/concepts/provisioning/sync.adoc b/src/main/asciidoc/concepts/provisioning/sync.adoc
deleted file mode 100644
index 7bc130f..0000000
--- a/src/main/asciidoc/concepts/provisioning/sync.adoc
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-==== Synchronization
-Basically, the synchronization is the mechanism used by Apache Syncope to acquire user/group data from external resources.
-Synchronization can be "full" (full reconciliation) or "incremental".
-In the former case, each sync task execution will take over just of changes from the previous execution 
-(if exists and connector permits incremental sync).
-In the latter case, each sync task execution will take over of the entire set of data managed by the external resource.
-
-===== From an external resource to Syncope
-All the entity (user/group) data involved by a synchronization are retrieved from an external resource and processed 
-internally by Syncope itself.
-A retrieved entity can be:
-
-. a matching entity, if a corresponding local/internal entity has been found;
-. or an unmatching entity, otherwise.
-
-By default, Syncope will create locally all the unmatching entities (without linking entities and resources) and will 
-update all the matching ones.
-By the way, a different behaviour can be configured working with matching/unmatching rules.
-
-===== Matching and Unmatching rules
-Unmatching (corresponding user not found on Syncope):
-
-* IGNORE / UNLINK (do not perform any action);
-* ASSIGN (create entity linking the resource);
-* PROVISION (create entity without linking the resource).
-
-Matching (corresponding users found on Syncope):
-
-* IGNORE (do not perform any action);
-* UPDATE (update matching entity);
-* DEPROVISION (delete resource entity);
-* UNASSIGN (unlink resource and delete resource entity) ;
-* UNLINK (just unlink resource without performing any (de-)provisioning operation);
-* LINK (just link resource without performing any (de-)provisioning operation).
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/src/main/asciidoc/workingwithapachesyncope/cli/task.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/workingwithapachesyncope/cli/task.adoc b/src/main/asciidoc/workingwithapachesyncope/cli/task.adoc
index 5572442..9889956 100644
--- a/src/main/asciidoc/workingwithapachesyncope/cli/task.adoc
+++ b/src/main/asciidoc/workingwithapachesyncope/cli/task.adoc
@@ -29,7 +29,7 @@ Usage: task [options]
     --details
     --list
        Syntax: --list {TASK-TYPE} 
-          Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / SYNCHRONIZATION
+          Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / PULL
     --list-running-jobs
     --list-scheduled-jobs
     --read 


[11/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 582cd18..c9ef66a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -33,7 +33,7 @@ import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.AbstractTask;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
@@ -63,8 +63,8 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
                 result = JPASchedTask.class;
                 break;
 
-            case SYNCHRONIZATION:
-                result = JPASyncTask.class;
+            case PULL:
+                result = JPAPullTask.class;
                 break;
 
             default:
@@ -116,7 +116,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
             final Long anyTypeKey) {
 
         if (resource != null
-                && type != TaskType.PROPAGATION && type != TaskType.PUSH && type != TaskType.SYNCHRONIZATION) {
+                && type != TaskType.PROPAGATION && type != TaskType.PUSH && type != TaskType.PULL) {
 
             throw new IllegalArgumentException(type + " is not related to " + ExternalResource.class.getSimpleName());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 5c8cc59..881f509 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.policy.JPASyncPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
@@ -49,7 +49,6 @@ import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.persistence.api.entity.ReportTemplate;
 import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
@@ -70,13 +69,11 @@ import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTaskAnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
@@ -106,12 +103,12 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTaskAnyFilter;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskExec;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
@@ -121,6 +118,9 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 @Component
 public class JPAEntityFactory implements EntityFactory {
@@ -142,8 +142,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAPasswordPolicy();
         } else if (reference.equals(PushPolicy.class)) {
             result = (T) new JPAPushPolicy();
-        } else if (reference.equals(SyncPolicy.class)) {
-            result = (T) new JPASyncPolicy();
+        } else if (reference.equals(PullPolicy.class)) {
+            result = (T) new JPAPullPolicy();
         } else if (reference.equals(AnyTypeClass.class)) {
             result = (T) new JPAAnyTypeClass();
         } else if (reference.equals(AnyType.class)) {
@@ -228,16 +228,16 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAPropagationTask();
         } else if (reference.equals(PushTask.class)) {
             result = (T) new JPAPushTask();
-        } else if (reference.equals(SyncTask.class)) {
-            result = (T) new JPASyncTask();
+        } else if (reference.equals(PullTask.class)) {
+            result = (T) new JPAPullTask();
         } else if (reference.equals(SchedTask.class)) {
             result = (T) new JPASchedTask();
         } else if (reference.equals(TaskExec.class)) {
             result = (T) new JPATaskExec();
         } else if (reference.equals(PushTaskAnyFilter.class)) {
             result = (T) new JPAPushTaskAnyFilter();
-        } else if (reference.equals(AnyTemplateSyncTask.class)) {
-            result = (T) new JPAAnyTemplateSyncTask();
+        } else if (reference.equals(AnyTemplatePullTask.class)) {
+            result = (T) new JPAAnyTemplatePullTask();
         } else if (reference.equals(SecurityQuestion.class)) {
             result = (T) new JPASecurityQuestion();
         } else if (reference.equals(Logger.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
new file mode 100644
index 0000000..c408b43
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.policy;
+
+import javax.persistence.Entity;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
+
+@Entity
+@Table(name = JPAPullPolicy.TABLE)
+public class JPAPullPolicy extends AbstractPolicy implements PullPolicy {
+
+    private static final long serialVersionUID = -6090413855809521279L;
+
+    public static final String TABLE = "PullPolicy";
+
+    @Lob
+    private String specification;
+
+    public JPAPullPolicy() {
+        super();
+        this.type = PolicyType.PULL;
+    }
+
+    @Override
+    public PullPolicySpec getSpecification() {
+        return POJOHelper.deserialize(specification, PullPolicySpec.class);
+    }
+
+    @Override
+    public void setSpecification(final PullPolicySpec policy) {
+        this.specification = POJOHelper.serialize(policy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
deleted file mode 100644
index 9d2a518..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity.policy;
-
-import javax.persistence.Entity;
-import javax.persistence.Lob;
-import javax.persistence.Table;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
-
-@Entity
-@Table(name = JPASyncPolicy.TABLE)
-public class JPASyncPolicy extends AbstractPolicy implements SyncPolicy {
-
-    private static final long serialVersionUID = -6090413855809521279L;
-
-    public static final String TABLE = "SyncPolicy";
-
-    @Lob
-    private String specification;
-
-    public JPASyncPolicy() {
-        super();
-        this.type = PolicyType.SYNC;
-    }
-
-    @Override
-    public SyncPolicySpec getSpecification() {
-        return POJOHelper.deserialize(specification, SyncPolicySpec.class);
-    }
-
-    @Override
-    public void setSpecification(final SyncPolicySpec policy) {
-        this.specification = POJOHelper.serialize(policy);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
index 5900f68..e4158ea 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -50,7 +50,6 @@ import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -60,11 +59,12 @@ import org.apache.syncope.core.persistence.jpa.entity.AbstractAnnotatedEntity;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.policy.JPASyncPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
 import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 /**
- * Resource for propagation and synchronization.
+ * Resource for propagation and pull.
  */
 @Entity
 @Table(name = JPAExternalResource.TABLE)
@@ -128,7 +128,7 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
 
     @Enumerated(EnumType.STRING)
     @NotNull
-    private TraceLevel syncTraceLevel;
+    private TraceLevel pullTraceLevel;
 
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAPasswordPolicy passwordPolicy;
@@ -137,7 +137,7 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
     private JPAAccountPolicy accountPolicy;
 
     @ManyToOne(fetch = FetchType.EAGER)
-    private JPASyncPolicy syncPolicy;
+    private JPAPullPolicy pullPolicy;
 
     /**
      * Configuration properties that are overridden from the connector instance.
@@ -180,7 +180,7 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
         createTraceLevel = TraceLevel.FAILURES;
         updateTraceLevel = TraceLevel.FAILURES;
         deleteTraceLevel = TraceLevel.FAILURES;
-        syncTraceLevel = TraceLevel.FAILURES;
+        pullTraceLevel = TraceLevel.FAILURES;
     }
 
     @Override
@@ -301,13 +301,13 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
     }
 
     @Override
-    public TraceLevel getSyncTraceLevel() {
-        return syncTraceLevel;
+    public TraceLevel getPullTraceLevel() {
+        return pullTraceLevel;
     }
 
     @Override
-    public void setSyncTraceLevel(final TraceLevel syncTraceLevel) {
-        this.syncTraceLevel = syncTraceLevel;
+    public void setPullTraceLevel(final TraceLevel pullTraceLevel) {
+        this.pullTraceLevel = pullTraceLevel;
     }
 
     @Override
@@ -333,14 +333,14 @@ public class JPAExternalResource extends AbstractAnnotatedEntity<String> impleme
     }
 
     @Override
-    public SyncPolicy getSyncPolicy() {
-        return syncPolicy;
+    public PullPolicy getPullPolicy() {
+        return pullPolicy;
     }
 
     @Override
-    public void setSyncPolicy(final SyncPolicy syncPolicy) {
-        checkType(syncPolicy, JPASyncPolicy.class);
-        this.syncPolicy = (JPASyncPolicy) syncPolicy;
+    public void setPullPolicy(final PullPolicy pullPolicy) {
+        checkType(pullPolicy, JPAPullPolicy.class);
+        this.pullPolicy = (JPAPullPolicy) pullPolicy;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 463408e..b2e2b61 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -41,7 +41,7 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
     private static final long serialVersionUID = -4141057723006682562L;
 
     /**
-     * ExternalResource to which the sync happens.
+     * ExternalResource to which pull happens.
      */
     @ManyToOne
     private JPAExternalResource resource;
@@ -64,7 +64,7 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
     @Basic
     @Min(0)
     @Max(1)
-    private Integer syncStatus;
+    private Integer pullStatus;
 
     /**
      * @see UnmatchingRule
@@ -89,7 +89,7 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
 
     @Override
     public void setJobDelegateClassName(final String jobClassName) {
-        // fixed to SyncJob, cannot be changed
+        // fixed to PullJob, cannot be changed
     }
 
     @Override
@@ -137,13 +137,13 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
     }
 
     @Override
-    public boolean isSyncStatus() {
-        return isBooleanAsInteger(syncStatus);
+    public boolean isPullStatus() {
+        return isBooleanAsInteger(pullStatus);
     }
 
     @Override
-    public void setSyncStatus(final boolean syncStatus) {
-        this.syncStatus = getBooleanAsInteger(syncStatus);
+    public void setPullStatus(final boolean pullStatus) {
+        this.pullStatus = getBooleanAsInteger(pullStatus);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java
new file mode 100644
index 0000000..66e37ff
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.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.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+
+@Entity
+@Table(name = JPAAnyTemplatePullTask.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "pullTask_id", "anyType_name" }))
+public class JPAAnyTemplatePullTask extends AbstractAnyTemplate implements AnyTemplatePullTask {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyTemplatePullTask";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAPullTask pullTask;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public PullTask getPullTask() {
+        return pullTask;
+    }
+
+    @Override
+    public void setPullTask(final PullTask pullTask) {
+        checkType(pullTask, JPAPullTask.class);
+        this.pullTask = (JPAPullTask) pullTask;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.java
deleted file mode 100644
index 3b23342..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplateSyncTask.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.persistence.jpa.entity.task;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
-import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
-
-@Entity
-@Table(name = JPAAnyTemplateSyncTask.TABLE, uniqueConstraints =
-        @UniqueConstraint(columnNames = { "syncTask_id", "anyType_name" }))
-public class JPAAnyTemplateSyncTask extends AbstractAnyTemplate implements AnyTemplateSyncTask {
-
-    private static final long serialVersionUID = 3517381731849788407L;
-
-    public static final String TABLE = "AnyTemplateSyncTask";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPASyncTask syncTask;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public SyncTask getSyncTask() {
-        return syncTask;
-    }
-
-    @Override
-    public void setSyncTask(final SyncTask syncTask) {
-        checkType(syncTask, JPASyncTask.class);
-        this.syncTask = (JPASyncTask) syncTask;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
new file mode 100644
index 0000000..e97b3c6
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.task;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.PullMode;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+
+@Entity
+@DiscriminatorValue("PullTask")
+public class JPAPullTask extends AbstractProvisioningTask implements PullTask {
+
+    private static final long serialVersionUID = -4141057723006682563L;
+
+    @Enumerated(EnumType.STRING)
+    @NotNull
+    private PullMode pullMode;
+
+    private String reconciliationFilterBuilderClassName;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPARealm destinationRealm;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "PullTask_actionsClassNames",
+            joinColumns =
+            @JoinColumn(name = "pullTask_id", referencedColumnName = "id"))
+    private Set<String> actionsClassNames = new HashSet<>();
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "pullTask")
+    private List<JPAAnyTemplatePullTask> templates = new ArrayList<>();
+
+    /**
+     * Default constructor.
+     */
+    public JPAPullTask() {
+        super(TaskType.PULL, null);
+    }
+
+    @Override
+    public PullMode getPullMode() {
+        return pullMode;
+    }
+
+    @Override
+    public void setPullMode(final PullMode pullMode) {
+        this.pullMode = pullMode;
+    }
+
+    @Override
+    public String getReconciliationFilterBuilderClassName() {
+        return reconciliationFilterBuilderClassName;
+    }
+
+    @Override
+    public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) {
+        this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName;
+    }
+
+    @Override
+    public Realm getDestinatioRealm() {
+        return destinationRealm;
+    }
+
+    @Override
+    public void setDestinationRealm(final Realm destinationRealm) {
+        checkType(destinationRealm, JPARealm.class);
+        this.destinationRealm = (JPARealm) destinationRealm;
+    }
+
+    @Override
+    public Set<String> getActionsClassNames() {
+        return actionsClassNames;
+    }
+
+    @Override
+    public boolean add(final AnyTemplatePullTask template) {
+        checkType(template, JPAAnyTemplatePullTask.class);
+        return this.templates.add((JPAAnyTemplatePullTask) template);
+    }
+
+    @Override
+    public AnyTemplatePullTask getTemplate(final AnyType anyType) {
+        return IterableUtils.find(templates, new Predicate<AnyTemplate>() {
+
+            @Override
+            public boolean evaluate(final AnyTemplate template) {
+                return anyType != null && anyType.equals(template.getAnyType());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends AnyTemplatePullTask> getTemplates() {
+        return templates;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTaskAnyFilter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTaskAnyFilter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTaskAnyFilter.java
index 5a310ba..6051f1e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTaskAnyFilter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTaskAnyFilter.java
@@ -62,9 +62,9 @@ public class JPAPushTaskAnyFilter extends AbstractEntity<Long> implements PushTa
     }
 
     @Override
-    public void setPushTask(final PushTask syncTask) {
-        checkType(syncTask, JPAPushTask.class);
-        this.pushTask = (JPAPushTask) syncTask;
+    public void setPushTask(final PushTask pushTask) {
+        checkType(pushTask, JPAPushTask.class);
+        this.pushTask = (JPAPushTask) pushTask;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
deleted file mode 100644
index 30b654e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity.task;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.CollectionTable;
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.ElementCollection;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.validation.constraints.NotNull;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
-import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
-
-@Entity
-@DiscriminatorValue("SyncTask")
-public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
-
-    private static final long serialVersionUID = -4141057723006682563L;
-
-    @Enumerated(EnumType.STRING)
-    @NotNull
-    private SyncMode syncMode;
-
-    private String reconciliationFilterBuilderClassName;
-
-    @ManyToOne(fetch = FetchType.EAGER, optional = false)
-    private JPARealm destinationRealm;
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    @Column(name = "actionClassName")
-    @CollectionTable(name = "SyncTask_actionsClassNames",
-            joinColumns =
-            @JoinColumn(name = "syncTask_id", referencedColumnName = "id"))
-    private Set<String> actionsClassNames = new HashSet<>();
-
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
-    private List<JPAAnyTemplateSyncTask> templates = new ArrayList<>();
-
-    /**
-     * Default constructor.
-     */
-    public JPASyncTask() {
-        super(TaskType.SYNCHRONIZATION, null);
-    }
-
-    @Override
-    public SyncMode getSyncMode() {
-        return syncMode;
-    }
-
-    @Override
-    public void setSyncMode(final SyncMode syncMode) {
-        this.syncMode = syncMode;
-    }
-
-    @Override
-    public String getReconciliationFilterBuilderClassName() {
-        return reconciliationFilterBuilderClassName;
-    }
-
-    @Override
-    public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) {
-        this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName;
-    }
-
-    @Override
-    public Realm getDestinatioRealm() {
-        return destinationRealm;
-    }
-
-    @Override
-    public void setDestinationRealm(final Realm destinationRealm) {
-        checkType(destinationRealm, JPARealm.class);
-        this.destinationRealm = (JPARealm) destinationRealm;
-    }
-
-    @Override
-    public Set<String> getActionsClassNames() {
-        return actionsClassNames;
-    }
-
-    @Override
-    public boolean add(final AnyTemplateSyncTask template) {
-        checkType(template, JPAAnyTemplateSyncTask.class);
-        return this.templates.add((JPAAnyTemplateSyncTask) template);
-    }
-
-    @Override
-    public AnyTemplateSyncTask getTemplate(final AnyType anyType) {
-        return IterableUtils.find(templates, new Predicate<AnyTemplate>() {
-
-            @Override
-            public boolean evaluate(final AnyTemplate template) {
-                return anyType != null && anyType.equals(template.getAnyType());
-            }
-        });
-    }
-
-    @Override
-    public List<? extends AnyTemplateSyncTask> getTemplates() {
-        return templates;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
index 484af1e..0905533 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
@@ -23,15 +23,15 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 
 @SuppressWarnings("unchecked")
 public final class JPATaskUtils implements TaskUtils {
@@ -60,8 +60,8 @@ public final class JPATaskUtils implements TaskUtils {
                 result = (Class<T>) SchedTask.class;
                 break;
 
-            case SYNCHRONIZATION:
-                result = (Class<T>) SyncTask.class;
+            case PULL:
+                result = (Class<T>) PullTask.class;
                 break;
 
             case PUSH:
@@ -91,8 +91,8 @@ public final class JPATaskUtils implements TaskUtils {
                 result = (T) new JPASchedTask();
                 break;
 
-            case SYNCHRONIZATION:
-                result = (T) new JPASyncTask();
+            case PULL:
+                result = (T) new JPAPullTask();
                 break;
 
             case PUSH:
@@ -122,8 +122,8 @@ public final class JPATaskUtils implements TaskUtils {
                 result = (Class<T>) SchedTaskTO.class;
                 break;
 
-            case SYNCHRONIZATION:
-                result = (Class<T>) SyncTaskTO.class;
+            case PULL:
+                result = (Class<T>) PullTaskTO.class;
                 break;
 
             case PUSH:

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
index 26a1d4f..a26debd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
@@ -23,17 +23,17 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 
 @Component
 public class JPATaskUtilsFactory implements TaskUtilsFactory {
@@ -46,8 +46,8 @@ public class JPATaskUtilsFactory implements TaskUtilsFactory {
     @Override
     public TaskUtils getInstance(final Task task) {
         TaskType type;
-        if (task instanceof SyncTask) {
-            type = TaskType.SYNCHRONIZATION;
+        if (task instanceof PullTask) {
+            type = TaskType.PULL;
         } else if (task instanceof PushTask) {
             type = TaskType.PUSH;
         } else if (task instanceof SchedTask) {
@@ -72,8 +72,8 @@ public class JPATaskUtilsFactory implements TaskUtilsFactory {
             type = TaskType.NOTIFICATION;
         } else if (taskClass == SchedTaskTO.class) {
             type = TaskType.SCHEDULED;
-        } else if (taskClass == SyncTaskTO.class) {
-            type = TaskType.SYNCHRONIZATION;
+        } else if (taskClass == PullTaskTO.class) {
+            type = TaskType.PULL;
         } else if (taskClass == PushTaskTO.class) {
             type = TaskType.PUSH;
         } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
index a48f4c6..e5c053c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
@@ -33,7 +33,7 @@ import javax.validation.Payload;
 @Documented
 public @interface ProvisioningTaskCheck {
 
-    String message() default "{org.apache.syncope.core.persistence.validation.abstractsynctask}";
+    String message() default "{org.apache.syncope.core.persistence.validation.provisioningtask}";
 
     Class<?>[] groups() default {};
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
index da90bd4..ef20ace 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -20,14 +20,14 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
-import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask;
-import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 
 public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
 
@@ -60,14 +60,14 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                     boolean isAssignable = false;
                     try {
                         actionsClass = Class.forName(className);
-                        isAssignable = task instanceof JPASyncTask
-                                ? SyncActions.class.isAssignableFrom(actionsClass)
+                        isAssignable = task instanceof JPAPullTask
+                                ? PullActions.class.isAssignableFrom(actionsClass)
                                 : task instanceof JPAPushTask
                                         ? PushActions.class.isAssignableFrom(actionsClass)
                                         : false;
                     } catch (Exception e) {
                         LOG.error("Invalid {} / {} specified",
-                                PushActions.class.getName(), SyncActions.class.getName(), e);
+                                PushActions.class.getName(), PullActions.class.getName(), e);
                         isValid = false;
                     }
 
@@ -82,17 +82,17 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                 }
             }
 
-            if (isValid && task instanceof SyncTask
-                    && ((SyncTask) task).getSyncMode() == SyncMode.FILTERED_RECONCILIATION) {
+            if (isValid && task instanceof PullTask
+                    && ((PullTask) task).getPullMode() == PullMode.FILTERED_RECONCILIATION) {
 
                 Class<?> filterBuilderClass = null;
                 boolean isAssignable = false;
                 try {
-                    filterBuilderClass = Class.forName(((SyncTask) task).getReconciliationFilterBuilderClassName());
+                    filterBuilderClass = Class.forName(((PullTask) task).getReconciliationFilterBuilderClassName());
                     isAssignable = ReconciliationFilterBuilder.class.isAssignableFrom(filterBuilderClass);
                 } catch (Exception e) {
                     LOG.error("Invalid {} specified",
-                            ReconciliationFilterBuilder.class.getName(), SyncActions.class.getName(), e);
+                            ReconciliationFilterBuilder.class.getName(), PullActions.class.getName(), e);
                     isValid = false;
                 }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index 72fadcd..42cb116 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
@@ -320,11 +320,11 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplatePullTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplatePullTask" pk-column-value="SEQ_AnyTemplatePullTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index 72fadcd..42cb116 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
@@ -320,11 +320,11 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplatePullTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplatePullTask" pk-column-value="SEQ_AnyTemplatePullTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index 5fc68ea..721916c 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -368,11 +368,11 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplateSyncTask">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_AnyTemplateSyncTask" strategy="TABLE"/>
-        <table-generator name="SEQ_AnyTemplateSyncTask" pk-column-value="SEQ_AnyTemplateSyncTask" initial-value="1000"/>
+        <generated-value generator="SEQ_AnyTemplatePullTask" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplatePullTask" pk-column-value="SEQ_AnyTemplatePullTask" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index 6762b7f..426a3de 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -29,17 +29,17 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 @Transactional("Master")
 public class PolicyTest extends AbstractTest {
@@ -59,10 +59,10 @@ public class PolicyTest extends AbstractTest {
 
     @Test
     public void findByKey() {
-        SyncPolicy policy = policyDAO.find(3L);
+        PullPolicy policy = policyDAO.find(3L);
         assertNotNull("findById did not work", policy);
 
-        SyncPolicySpec spec = policy.getSpecification();
+        PullPolicySpec spec = policy.getSpecification();
         assertNotNull(spec);
 
         String rule = spec.getCorrelationRules().get(AnyTypeKind.USER.name());
@@ -76,33 +76,33 @@ public class PolicyTest extends AbstractTest {
 
     @Test
     public void findByType() {
-        List<? extends Policy> policies = policyDAO.find(PolicyType.SYNC);
+        List<? extends Policy> policies = policyDAO.find(PolicyType.PULL);
         assertNotNull("findById did not work", policies);
         assertFalse(policies.isEmpty());
     }
 
     @Test
     public void create() {
-        SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
+        PullPolicy policy = entityFactory.newEntity(PullPolicy.class);
 
-        final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
-        final String syncGRuleName = "net.tirasa.sync.correlation.TirasaGRule";
+        final String pullURuleName = "net.tirasa.pull.correlation.TirasaURule";
+        final String pullGRuleName = "net.tirasa.pull.correlation.TirasaGRule";
 
-        SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
+        PullPolicySpec pullPolicySpec = new PullPolicySpec();
 
-        syncPolicySpec.getCorrelationRules().put(anyTypeDAO.findUser().getKey(), syncURuleName);
-        syncPolicySpec.getCorrelationRules().put(anyTypeDAO.findGroup().getKey(), syncGRuleName);
+        pullPolicySpec.getCorrelationRules().put(anyTypeDAO.findUser().getKey(), pullURuleName);
+        pullPolicySpec.getCorrelationRules().put(anyTypeDAO.findGroup().getKey(), pullGRuleName);
 
-        policy.setSpecification(syncPolicySpec);
-        policy.setDescription("Sync policy");
+        policy.setSpecification(pullPolicySpec);
+        policy.setDescription("Pull policy");
 
         policy = policyDAO.save(policy);
 
         assertNotNull(policy);
-        assertEquals(PolicyType.SYNC, policy.getType());
-        assertEquals(syncURuleName,
+        assertEquals(PolicyType.PULL, policy.getType());
+        assertEquals(pullURuleName,
                 policy.getSpecification().getCorrelationRules().get(anyTypeDAO.findUser().getKey()));
-        assertEquals(syncGRuleName,
+        assertEquals(pullGRuleName,
                 policy.getSpecification().getCorrelationRules().get(anyTypeDAO.findGroup().getKey()));
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
index f39f06f..038030e 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -98,7 +98,7 @@ public class TaskTest extends AbstractTest {
         assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
-        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(10, taskDAO.findAll(TaskType.PULL).size());
         assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
index ab0b88b..a484ac7 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
@@ -156,7 +156,7 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void deleteALong() {
-        assertEquals(6, resourceDAO.find("resource-db-sync").
+        assertEquals(6, resourceDAO.find("resource-db-pull").
                 getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
 
         plainSchemaDAO.delete("aLong");
@@ -164,7 +164,7 @@ public class PlainSchemaTest extends AbstractTest {
 
         plainSchemaDAO.flush();
 
-        assertEquals(5, resourceDAO.find("resource-db-sync").
+        assertEquals(5, resourceDAO.find("resource-db-pull").
                 getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
index 6f7e8be..3df840b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -134,7 +134,7 @@ public class ResourceTest extends AbstractTest {
             item.setIntAttrName("nonexistent" + i);
             item.setIntMappingType(IntMappingType.UserPlainSchema);
             item.setMandatoryCondition("false");
-            item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+            item.setPurpose(MappingPurpose.PULL);
             mapping.add(item);
             item.setMapping(mapping);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index 6c00347..4edc498 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -33,7 +33,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
@@ -45,17 +45,17 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 
 @Transactional("Master")
 public class TaskTest extends AbstractTest {
@@ -139,8 +139,8 @@ public class TaskTest extends AbstractTest {
     }
 
     @Test
-    public void addSyncTaskExecution() {
-        SyncTask task = taskDAO.find(4L);
+    public void addPullTaskExecution() {
+        PullTask task = taskDAO.find(4L);
         assertNotNull(task);
 
         int executionNumber = task.getExecs().size();
@@ -210,18 +210,18 @@ public class TaskTest extends AbstractTest {
     }
 
     @Test
-    public void saveSyncTask() {
+    public void savePullTask() {
         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
         assertNotNull(resource);
 
-        AnyTemplateSyncTask template = entityFactory.newEntity(AnyTemplateSyncTask.class);
+        AnyTemplatePullTask template = entityFactory.newEntity(AnyTemplatePullTask.class);
         template.set(new UserTO());
 
-        SyncTask task = entityFactory.newEntity(SyncTask.class);
-        task.setName("saveSyncTask");
-        task.setDescription("SyncTask description");
+        PullTask task = entityFactory.newEntity(PullTask.class);
+        task.setName("savePullTask");
+        task.setDescription("PullTask description");
         task.setActive(true);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
         task.add(template);
         task.setCronExpression("BLA BLA");
         task.setMatchingRule(MatchingRule.UPDATE);
@@ -237,7 +237,7 @@ public class TaskTest extends AbstractTest {
         assertNotNull(exception);
 
         task.setCronExpression(null);
-        // this save() fails because a SyncTask requires a target resource
+        // this save() fails because a PullTask requires a target resource
         exception = null;
         try {
             taskDAO.save(task);
@@ -260,12 +260,12 @@ public class TaskTest extends AbstractTest {
         assertNotNull(exception);
 
         task.getActionsClassNames().clear();
-        task.getActionsClassNames().add(SyncActions.class.getName());
+        task.getActionsClassNames().add(PullActions.class.getName());
         // this save() finally works
         task = taskDAO.save(task);
         assertNotNull(task);
 
-        SyncTask actual = taskDAO.find(task.getKey());
+        PullTask actual = taskDAO.find(task.getKey());
         assertEquals(task, actual);
     }
 
@@ -274,21 +274,21 @@ public class TaskTest extends AbstractTest {
         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
         assertNotNull(resource);
 
-        SyncTask task = entityFactory.newEntity(SyncTask.class);
+        PullTask task = entityFactory.newEntity(PullTask.class);
 
         task.setResource(resource);
         task.setName("issueSYNCOPE144");
         task.setDescription("issueSYNCOPE144 Description");
         task.setActive(true);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        task.getActionsClassNames().add(SyncActions.class.getName());
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
+        task.getActionsClassNames().add(PullActions.class.getName());
         task.setMatchingRule(MatchingRule.UPDATE);
         task.setUnmatchingRule(UnmatchingRule.PROVISION);
 
         task = taskDAO.save(task);
         assertNotNull(task);
 
-        SyncTask actual = taskDAO.find(task.getKey());
+        PullTask actual = taskDAO.find(task.getKey());
         assertEquals(task, actual);
         assertEquals("issueSYNCOPE144", actual.getName());
         assertEquals("issueSYNCOPE144 Description", actual.getDescription());


[08/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
index 42de46f..7771f06 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
@@ -65,7 +65,7 @@ public class RealmDataBinderImpl implements RealmDataBinder {
 
     private void setTemplates(final RealmTO realmTO, final Realm realm) {
         // validate JEXL expressions from templates and proceed if fine
-        templateUtils.check(realmTO.getTemplates(), ClientExceptionType.InvalidSyncTask);
+        templateUtils.check(realmTO.getTemplates(), ClientExceptionType.InvalidPullTask);
         for (Map.Entry<String, AnyTO> entry : realmTO.getTemplates().entrySet()) {
             AnyType type = anyTypeDAO.find(entry.getKey());
             if (type == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index 97aa6f2..b4aa8b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -41,7 +41,6 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,6 +53,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 @Component
 public class ResourceDataBinderImpl implements ResourceDataBinder {
@@ -178,7 +178,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
         resource.setUpdateTraceLevel(resourceTO.getUpdateTraceLevel());
         resource.setDeleteTraceLevel(resourceTO.getDeleteTraceLevel());
-        resource.setSyncTraceLevel(resourceTO.getSyncTraceLevel());
+        resource.setPullTraceLevel(resourceTO.getPullTraceLevel());
 
         resource.setPasswordPolicy(resourceTO.getPasswordPolicy() == null
                 ? null : (PasswordPolicy) policyDAO.find(resourceTO.getPasswordPolicy()));
@@ -186,8 +186,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resource.setAccountPolicy(resourceTO.getAccountPolicy() == null
                 ? null : (AccountPolicy) policyDAO.find(resourceTO.getAccountPolicy()));
 
-        resource.setSyncPolicy(resourceTO.getSyncPolicy() == null
-                ? null : (SyncPolicy) policyDAO.find(resourceTO.getSyncPolicy()));
+        resource.setPullPolicy(resourceTO.getPullPolicy() == null
+                ? null : (PullPolicy) policyDAO.find(resourceTO.getPullPolicy()));
 
         resource.setConfOverride(new HashSet<>(resourceTO.getConfOverride()));
 
@@ -340,7 +340,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resourceTO.setCreateTraceLevel(resource.getCreateTraceLevel());
         resourceTO.setUpdateTraceLevel(resource.getUpdateTraceLevel());
         resourceTO.setDeleteTraceLevel(resource.getDeleteTraceLevel());
-        resourceTO.setSyncTraceLevel(resource.getSyncTraceLevel());
+        resourceTO.setPullTraceLevel(resource.getPullTraceLevel());
 
         resourceTO.setPasswordPolicy(resource.getPasswordPolicy() == null
                 ? null : resource.getPasswordPolicy().getKey());
@@ -348,8 +348,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resourceTO.setAccountPolicy(resource.getAccountPolicy() == null
                 ? null : resource.getAccountPolicy().getKey());
 
-        resourceTO.setSyncPolicy(resource.getSyncPolicy() == null
-                ? null : resource.getSyncPolicy().getKey());
+        resourceTO.setPullPolicy(resource.getPullPolicy() == null
+                ? null : resource.getPullPolicy().getKey());
 
         resourceTO.getConfOverride().addAll(resource.getConfOverride());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index e262521..7679ce0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -30,7 +30,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.JobType;
@@ -46,7 +46,6 @@ import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
@@ -58,9 +57,10 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
-import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
-import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -142,46 +142,46 @@ public class TaskDataBinderImpl implements TaskDataBinder {
                     return pushTaskTO.getFilters().containsKey(anyFilter.getAnyType().getKey());
                 }
             });
-        } else if (task instanceof SyncTask && taskTO instanceof SyncTaskTO) {
-            SyncTask syncTask = (SyncTask) task;
-            final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO;
+        } else if (task instanceof PullTask && taskTO instanceof PullTaskTO) {
+            PullTask pullTask = (PullTask) task;
+            final PullTaskTO pullTaskTO = (PullTaskTO) taskTO;
 
-            syncTask.setSyncMode(syncTaskTO.getSyncMode());
-            syncTask.setReconciliationFilterBuilderClassName(syncTaskTO.getReconciliationFilterBuilderClassName());
+            pullTask.setPullMode(pullTaskTO.getPullMode());
+            pullTask.setReconciliationFilterBuilderClassName(pullTaskTO.getReconciliationFilterBuilderClassName());
 
-            syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
+            pullTask.setDestinationRealm(realmDAO.find(pullTaskTO.getDestinationRealm()));
 
-            syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName());
+            pullTask.setJobDelegateClassName(PullJobDelegate.class.getName());
 
-            syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
-                    ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
-            syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
-                    ? UnmatchingRule.PROVISION : syncTaskTO.getUnmatchingRule());
+            pullTask.setMatchingRule(pullTaskTO.getMatchingRule() == null
+                    ? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
+            pullTask.setUnmatchingRule(pullTaskTO.getUnmatchingRule() == null
+                    ? UnmatchingRule.PROVISION : pullTaskTO.getUnmatchingRule());
 
             // validate JEXL expressions from templates and proceed if fine
-            templateUtils.check(syncTaskTO.getTemplates(), ClientExceptionType.InvalidSyncTask);
-            for (Map.Entry<String, AnyTO> entry : syncTaskTO.getTemplates().entrySet()) {
+            templateUtils.check(pullTaskTO.getTemplates(), ClientExceptionType.InvalidPullTask);
+            for (Map.Entry<String, AnyTO> entry : pullTaskTO.getTemplates().entrySet()) {
                 AnyType type = anyTypeDAO.find(entry.getKey());
                 if (type == null) {
                     LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
                 } else {
-                    AnyTemplateSyncTask anyTemplate = syncTask.getTemplate(type);
+                    AnyTemplatePullTask anyTemplate = pullTask.getTemplate(type);
                     if (anyTemplate == null) {
-                        anyTemplate = entityFactory.newEntity(AnyTemplateSyncTask.class);
+                        anyTemplate = entityFactory.newEntity(AnyTemplatePullTask.class);
                         anyTemplate.setAnyType(type);
-                        anyTemplate.setSyncTask(syncTask);
+                        anyTemplate.setPullTask(pullTask);
 
-                        syncTask.add(anyTemplate);
+                        pullTask.add(anyTemplate);
                     }
                     anyTemplate.set(entry.getValue());
                 }
             }
             // remove all templates not contained in the TO
-            CollectionUtils.filter(syncTask.getTemplates(), new Predicate<AnyTemplate>() {
+            CollectionUtils.filter(pullTask.getTemplates(), new Predicate<AnyTemplate>() {
 
                 @Override
                 public boolean evaluate(final AnyTemplate anyTemplate) {
-                    return syncTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey());
+                    return pullTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey());
                 }
             });
         }
@@ -190,7 +190,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         task.setPerformCreate(taskTO.isPerformCreate());
         task.setPerformUpdate(taskTO.isPerformUpdate());
         task.setPerformDelete(taskTO.isPerformDelete());
-        task.setSyncStatus(taskTO.isSyncStatus());
+        task.setPullStatus(taskTO.isPullStatus());
         task.getActionsClassNames().clear();
         task.getActionsClassNames().addAll(taskTO.getActionsClassNames());
     }
@@ -334,21 +334,21 @@ public class TaskDataBinderImpl implements TaskDataBinder {
                 setExecTime((SchedTaskTO) taskTO, task);
                 break;
 
-            case SYNCHRONIZATION:
-                if (!(task instanceof SyncTask)) {
-                    throw new IllegalArgumentException("taskUtils is type Sync but task is not SyncTask: "
+            case PULL:
+                if (!(task instanceof PullTask)) {
+                    throw new IllegalArgumentException("taskUtils is type Pull but task is not PullTask: "
                             + task.getClass().getName());
                 }
                 setExecTime((SchedTaskTO) taskTO, task);
-                ((SyncTaskTO) taskTO).setDestinationRealm(((SyncTask) task).getDestinatioRealm().getFullPath());
-                ((SyncTaskTO) taskTO).setResource(((SyncTask) task).getResource().getKey());
-                ((SyncTaskTO) taskTO).setMatchingRule(((SyncTask) task).getMatchingRule() == null
-                        ? MatchingRule.UPDATE : ((SyncTask) task).getMatchingRule());
-                ((SyncTaskTO) taskTO).setUnmatchingRule(((SyncTask) task).getUnmatchingRule() == null
-                        ? UnmatchingRule.PROVISION : ((SyncTask) task).getUnmatchingRule());
-
-                for (AnyTemplate template : ((SyncTask) task).getTemplates()) {
-                    ((SyncTaskTO) taskTO).getTemplates().put(template.getAnyType().getKey(), template.get());
+                ((PullTaskTO) taskTO).setDestinationRealm(((PullTask) task).getDestinatioRealm().getFullPath());
+                ((PullTaskTO) taskTO).setResource(((PullTask) task).getResource().getKey());
+                ((PullTaskTO) taskTO).setMatchingRule(((PullTask) task).getMatchingRule() == null
+                        ? MatchingRule.UPDATE : ((PullTask) task).getMatchingRule());
+                ((PullTaskTO) taskTO).setUnmatchingRule(((PullTask) task).getUnmatchingRule() == null
+                        ? UnmatchingRule.PROVISION : ((PullTask) task).getUnmatchingRule());
+
+                for (AnyTemplate template : ((PullTask) task).getTemplates()) {
+                    ((PullTaskTO) taskTO).getTemplates().put(template.getAnyType().getKey(), template.get());
                 }
                 break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 6aa076e..4c6455b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -46,7 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
  * Simple action for propagating group memberships to LDAP groups, when the same resource is configured for both users
  * and groups.
  *
- * @see org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions
+ * @see org.apache.syncope.core.provisioning.java.pushpull.LDAPMembershipPullActions
  */
 public class LDAPMembershipPropagationActions extends DefaultPropagationActions {
 

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
new file mode 100644
index 0000000..bde6ee7
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -0,0 +1,797 @@
+/*
+ * 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.pushpull;
+
+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.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+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.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+
+@Transactional(rollbackFor = Throwable.class)
+public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHandler<PullTask, PullActions>
+        implements SyncopePullResultHandler {
+
+    @Autowired
+    protected PullUtils pullUtils;
+
+    @Autowired
+    protected VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    protected VirAttrCache virAttrCache;
+
+    protected abstract String getName(AnyTO anyTO);
+
+    protected abstract ProvisioningManager<?, ?> getProvisioningManager();
+
+    protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningReport result);
+
+    protected AnyTO doLink(final AnyTO before, final boolean unlink) {
+        AnyPatch patch = newPatch(before.getKey());
+        patch.setKey(before.getKey());
+        patch.getResources().add(new StringPatchItem.Builder().
+                operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
+                value(profile.getTask().getResource().getKey()).build());
+
+        return getAnyTO(update(patch).getResult());
+    }
+
+    protected abstract AnyTO doUpdate(AnyTO before, AnyPatch anyPatch, SyncDelta delta, ProvisioningReport result);
+
+    protected void doDeprovision(final AnyTypeKind kind, final Long key, final boolean unlink) {
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+        taskExecutor.execute(propagationManager.getDeleteTasks(
+                kind,
+                key,
+                propByRes,
+                null));
+
+        if (unlink) {
+            AnyPatch anyObjectPatch = newPatch(key);
+            anyObjectPatch.getResources().add(new StringPatchItem.Builder().
+                    operation(PatchOperation.DELETE).
+                    value(profile.getTask().getResource().getKey()).build());
+        }
+    }
+
+    protected void doDelete(final AnyTypeKind kind, final Long key) {
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+        try {
+            taskExecutor.execute(propagationManager.getDeleteTasks(
+                    kind,
+                    key,
+                    propByRes,
+                    null));
+        } catch (Exception e) {
+            // A propagation failure doesn't imply a pull failure.
+            // The propagation exception status will be reported into the propagation task execution.
+            LOG.error("Could not propagate anyObject " + key, e);
+        }
+
+        getProvisioningManager().delete(key, true);
+    }
+
+    @Override
+    public boolean handle(final SyncDelta delta) {
+        Provision provision = null;
+        try {
+            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) {
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.NONE);
+            result.setAnyType(provision == null
+                    ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
+            result.setStatus(ProvisioningReport.Status.IGNORE);
+            result.setKey(0L);
+            result.setName(delta.getObject().getName().getNameValue());
+            profile.getResults().add(result);
+
+            LOG.warn("Ignoring during pull", e);
+            return true;
+        } catch (JobExecutionException e) {
+            LOG.error("Pull failed", e);
+            return false;
+        }
+    }
+
+    protected List<ProvisioningReport> assign(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
+            throws JobExecutionException {
+
+        if (!profile.getTask().isPerformCreate()) {
+            LOG.debug("PullTask not configured for create");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
+
+        anyTO.getResources().add(profile.getTask().getResource().getKey());
+
+        ProvisioningReport result = new ProvisioningReport();
+        result.setOperation(ResourceOperation.CREATE);
+        result.setAnyType(provision.getAnyType().getKey());
+        result.setStatus(ProvisioningReport.Status.SUCCESS);
+        result.setName(getName(anyTO));
+
+        if (profile.isDryRun()) {
+            result.setKey(0L);
+        } else {
+            SyncDelta actionedDelta = delta;
+            for (PullActions action : profile.getActions()) {
+                actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, anyTO);
+            }
+
+            create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+        }
+
+        return Collections.singletonList(result);
+    }
+
+    protected List<ProvisioningReport> provision(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
+            throws JobExecutionException {
+
+        if (!profile.getTask().isPerformCreate()) {
+            LOG.debug("PullTask not configured for create");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
+
+        ProvisioningReport result = new ProvisioningReport();
+        result.setOperation(ResourceOperation.CREATE);
+        result.setAnyType(provision.getAnyType().getKey());
+        result.setStatus(ProvisioningReport.Status.SUCCESS);
+        result.setName(getName(anyTO));
+
+        if (profile.isDryRun()) {
+            result.setKey(0L);
+        } else {
+            SyncDelta actionedDelta = delta;
+            for (PullActions action : profile.getActions()) {
+                actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, anyTO);
+            }
+
+            create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+        }
+
+        return Collections.singletonList(result);
+    }
+
+    private void create(
+            final AnyTO anyTO,
+            final SyncDelta delta,
+            final String operation,
+            final ProvisioningReport result)
+            throws JobExecutionException {
+
+        Object output;
+        Result resultStatus;
+
+        try {
+            AnyTO actual = doCreate(anyTO, delta, result);
+            result.setName(getName(actual));
+            output = actual;
+            resultStatus = Result.SUCCESS;
+
+            for (PullActions action : profile.getActions()) {
+                action.after(this.getProfile(), delta, actual, result);
+            }
+        } catch (IgnoreProvisionException e) {
+            throw e;
+        } catch (PropagationException e) {
+            // A propagation failure doesn't imply a pull failure.
+            // The propagation exception status will be reported into the propagation task execution.
+            LOG.error("Could not propagate {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
+            output = e;
+            resultStatus = Result.FAILURE;
+
+            for (PullActions action : profile.getActions()) {
+                action.onError(this.getProfile(), delta, result, e);
+            }
+        } catch (Exception e) {
+            result.setStatus(ProvisioningReport.Status.FAILURE);
+            result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+            LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
+            output = e;
+            resultStatus = Result.FAILURE;
+
+            for (PullActions action : profile.getActions()) {
+                action.onError(this.getProfile(), delta, result, e);
+            }
+        }
+
+        audit(operation, resultStatus, null, output, delta);
+    }
+
+    protected List<ProvisioningReport> update(final SyncDelta delta, final List<Long> anys,
+            final Provision provision) throws JobExecutionException {
+
+        if (!profile.getTask().isPerformUpdate()) {
+            LOG.debug("PullTask not configured for update");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        LOG.debug("About to update {}", anys);
+
+        List<ProvisioningReport> results = new ArrayList<>();
+
+        SyncDelta workingDelta = delta;
+        for (Long key : anys) {
+            LOG.debug("About to update {}", key);
+
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.UPDATE);
+            result.setAnyType(provision.getAnyType().getKey());
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
+
+            AnyTO before = getAnyTO(key);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+            } else {
+                result.setName(getName(before));
+            }
+
+            Result resultStatus;
+            Object output;
+            if (!profile.isDryRun()) {
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
+                } else {
+                    try {
+                        AnyPatch anyPatch = connObjectUtils.getAnyPatch(
+                                before.getKey(),
+                                workingDelta.getObject(),
+                                before,
+                                profile.getTask(),
+                                provision,
+                                getAnyUtils());
+
+                        for (PullActions action : profile.getActions()) {
+                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyPatch);
+                        }
+
+                        AnyTO updated = doUpdate(before, anyPatch, workingDelta, result);
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(this.getProfile(), workingDelta, updated, result);
+                        }
+
+                        output = updated;
+                        resultStatus = Result.SUCCESS;
+                        result.setName(getName(updated));
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
+                    } catch (Exception e) {
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
+                    }
+                }
+                audit(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
+            }
+            results.add(result);
+        }
+        return results;
+    }
+
+    protected List<ProvisioningReport> deprovision(
+            final SyncDelta delta,
+            final List<Long> anys,
+            final Provision provision,
+            final boolean unlink)
+            throws JobExecutionException {
+
+        if (!profile.getTask().isPerformUpdate()) {
+            LOG.debug("PullTask not configured for update");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        LOG.debug("About to update {}", anys);
+
+        final List<ProvisioningReport> updResults = new ArrayList<>();
+
+        for (Long key : anys) {
+            LOG.debug("About to unassign resource {}", key);
+
+            Object output;
+            Result resultStatus;
+
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.DELETE);
+            result.setAnyType(provision.getAnyType().getKey());
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
+
+            AnyTO before = getAnyTO(key);
+
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+            }
+
+            if (!profile.isDryRun()) {
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
+                } else {
+                    result.setName(getName(before));
+
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                action.beforeUnassign(this.getProfile(), delta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                action.beforeDeprovision(this.getProfile(), delta, before);
+                            }
+                        }
+
+                        doDeprovision(provision.getAnyType().getKind(), key, unlink);
+                        output = getAnyTO(key);
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
+                    } catch (Exception e) {
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
+                    }
+                }
+                audit(unlink
+                        ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+                        : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+            }
+            updResults.add(result);
+        }
+
+        return updResults;
+    }
+
+    protected List<ProvisioningReport> link(
+            final SyncDelta delta,
+            final List<Long> anys,
+            final Provision provision,
+            final boolean unlink)
+            throws JobExecutionException {
+
+        if (!profile.getTask().isPerformUpdate()) {
+            LOG.debug("PullTask not configured for update");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        LOG.debug("About to update {}", anys);
+
+        final List<ProvisioningReport> updResults = new ArrayList<>();
+
+        for (Long key : anys) {
+            LOG.debug("About to unassign resource {}", key);
+
+            Object output;
+            Result resultStatus;
+
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.NONE);
+            result.setAnyType(provision.getAnyType().getKey());
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
+
+            AnyTO before = getAnyTO(key);
+
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+            }
+
+            if (!profile.isDryRun()) {
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
+                } else {
+                    result.setName(getName(before));
+
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                action.beforeUnlink(this.getProfile(), delta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                action.beforeLink(this.getProfile(), delta, before);
+                            }
+                        }
+
+                        output = doLink(before, unlink);
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
+                    } catch (Exception e) {
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), delta, result, e);
+                        }
+                    }
+                }
+                audit(unlink ? MatchingRule.toEventName(MatchingRule.UNLINK)
+                        : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
+            }
+            updResults.add(result);
+        }
+
+        return updResults;
+    }
+
+    protected List<ProvisioningReport> delete(
+            final SyncDelta delta,
+            final List<Long> anys,
+            final Provision provision)
+            throws JobExecutionException {
+
+        if (!profile.getTask().isPerformDelete()) {
+            LOG.debug("PullTask not configured for delete");
+            return Collections.<ProvisioningReport>emptyList();
+        }
+
+        LOG.debug("About to delete {}", anys);
+
+        List<ProvisioningReport> delResults = new ArrayList<>();
+
+        SyncDelta workingDelta = delta;
+        for (Long key : anys) {
+            Object output;
+            Result resultStatus = Result.FAILURE;
+
+            ProvisioningReport result = new ProvisioningReport();
+
+            try {
+                AnyTO before = getAnyTO(key);
+
+                result.setKey(key);
+                result.setName(getName(before));
+                result.setOperation(ResourceOperation.DELETE);
+                result.setAnyType(provision.getAnyType().getKey());
+                result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+                if (!profile.isDryRun()) {
+                    for (PullActions action : profile.getActions()) {
+                        workingDelta = action.beforeDelete(this.getProfile(), workingDelta, before);
+                    }
+
+                    try {
+                        doDelete(provision.getAnyType().getKind(), key);
+                        output = null;
+                        resultStatus = Result.SUCCESS;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(this.getProfile(), workingDelta, before, result);
+                        }
+                    } catch (IgnoreProvisionException e) {
+                        throw e;
+                    } catch (Exception e) {
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
+                        output = e;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.onError(this.getProfile(), workingDelta, result, e);
+                        }
+                    }
+
+                    audit(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+                }
+
+                delResults.add(result);
+            } catch (NotFoundException e) {
+                LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
+            } catch (DelegatedAdministrationException e) {
+                LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), key, e);
+            } catch (Exception e) {
+                LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
+            }
+        }
+
+        return delResults;
+    }
+
+    private List<ProvisioningReport> ignore(
+            final SyncDelta delta,
+            final Provision provision,
+            final boolean matching)
+            throws JobExecutionException {
+
+        LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
+
+        final List<ProvisioningReport> ignoreResults = new ArrayList<>();
+        ProvisioningReport result = new ProvisioningReport();
+
+        result.setKey(null);
+        result.setName(delta.getObject().getUid().getUidValue());
+        result.setOperation(ResourceOperation.NONE);
+        result.setAnyType(provision.getAnyType().getKey());
+        result.setStatus(ProvisioningReport.Status.SUCCESS);
+        ignoreResults.add(result);
+
+        if (!profile.isDryRun()) {
+            audit(matching
+                    ? MatchingRule.toEventName(MatchingRule.IGNORE)
+                    : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
+        }
+
+        return ignoreResults;
+    }
+
+    /**
+     * 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 pull failure.
+     */
+    protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
+        AnyUtils anyUtils = getAnyUtils();
+
+        LOG.debug("Process {} for {} as {}",
+                delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
+
+        String uid = delta.getPreviousUid() == null
+                ? delta.getUid().getUidValue()
+                : delta.getPreviousUid().getUidValue();
+
+        try {
+            List<Long> anyKeys = pullUtils.findExisting(uid, delta.getObject(), provision, anyUtils);
+            LOG.debug("Match(es) found for {} as {}: {}",
+                    delta.getUid().getUidValue(), delta.getObject().getObjectClass(), anyKeys);
+
+            if (anyKeys.size() > 1) {
+                switch (profile.getResAct()) {
+                    case IGNORE:
+                        throw new IllegalStateException("More than one match " + anyKeys);
+
+                    case FIRSTMATCH:
+                        anyKeys = anyKeys.subList(0, 1);
+                        break;
+
+                    case LASTMATCH:
+                        anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
+                        break;
+
+                    default:
+                    // keep anyKeys unmodified
+                }
+            }
+
+            if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
+                if (anyKeys.isEmpty()) {
+                    switch (profile.getTask().getUnmatchingRule()) {
+                        case ASSIGN:
+                            profile.getResults().addAll(assign(delta, provision, anyUtils));
+                            break;
+
+                        case PROVISION:
+                            profile.getResults().addAll(provision(delta, provision, anyUtils));
+                            break;
+
+                        case IGNORE:
+                            profile.getResults().addAll(ignore(delta, provision, false));
+                            break;
+
+                        default:
+                        // do nothing
+                    }
+                } else {
+                    // update VirAttrCache
+                    for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
+                        Attribute attr = delta.getObject().getAttributeByName(virSchema.getExtAttrName());
+                        for (Long anyKey : anyKeys) {
+                            if (attr == null) {
+                                virAttrCache.expire(
+                                        provision.getAnyType().getKey(),
+                                        anyKey,
+                                        virSchema.getKey());
+                            } else {
+                                VirAttrCacheValue cacheValue = new VirAttrCacheValue();
+                                cacheValue.setValues(attr.getValue());
+                                virAttrCache.put(
+                                        provision.getAnyType().getKey(),
+                                        anyKey,
+                                        virSchema.getKey(),
+                                        cacheValue);
+                            }
+                        }
+                    }
+
+                    switch (profile.getTask().getMatchingRule()) {
+                        case UPDATE:
+                            profile.getResults().addAll(update(delta, anyKeys, provision));
+                            break;
+
+                        case DEPROVISION:
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
+                            break;
+
+                        case UNASSIGN:
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
+                            break;
+
+                        case LINK:
+                            profile.getResults().addAll(link(delta, anyKeys, provision, false));
+                            break;
+
+                        case UNLINK:
+                            profile.getResults().addAll(link(delta, anyKeys, provision, true));
+                            break;
+
+                        case IGNORE:
+                            profile.getResults().addAll(ignore(delta, provision, true));
+                            break;
+
+                        default:
+                        // do nothing
+                    }
+                }
+            } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
+                if (anyKeys.isEmpty()) {
+                    LOG.debug("No match found for deletion");
+                } else {
+                    profile.getResults().addAll(delete(delta, anyKeys, provision));
+                }
+            }
+        } catch (IllegalStateException | IllegalArgumentException e) {
+            LOG.warn(e.getMessage());
+        }
+    }
+
+    private void audit(
+            final String event,
+            final Result result,
+            final Object before,
+            final Object output,
+            final Object... input) {
+
+        notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
+                profile.getTask().getResource().getKey(),
+                event,
+                result,
+                before,
+                output,
+                input);
+
+        auditManager.audit(AuditElements.EventCategoryType.PULL,
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
+                profile.getTask().getResource().getKey(),
+                event,
+                result,
+                before,
+                output,
+                input);
+    }
+}


[03/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
deleted file mode 100644
index 2fb035c..0000000
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.apache.syncope.core.provisioning.camel.processor;
-
-/*
- * 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.
- */
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.springframework.stereotype.Component;
-
-@Component
-public class GroupCreateInSyncProcessor implements Processor {
-
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    @Autowired
-    protected PropagationTaskExecutor taskExecutor;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void process(final Exchange exchange) {
-        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
-
-        GroupTO groupTO = exchange.getProperty("any", GroupTO.class);
-        Map<Long, String> groupOwnerMap = exchange.getProperty("groupOwnerMap", Map.class);
-        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
-        Boolean nullPriorityAsync = exchange.getProperty("nullPriorityAsync", Boolean.class);
-
-        AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
-        if (groupOwner != null) {
-            groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
-        }
-
-        List<PropagationTask> tasks = propagationManager.getCreateTasks(
-                AnyTypeKind.GROUP,
-                created.getResult(),
-                created.getPropByRes(),
-                groupTO.getVirAttrs(),
-                excludedResources);
-        PropagationReporter propagationReporter =
-                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
-        taskExecutor.execute(tasks, propagationReporter, nullPriorityAsync);
-
-        exchange.getOut().setBody(new ImmutablePair<>(created.getResult(), null));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInPullProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInPullProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInPullProcessor.java
new file mode 100644
index 0000000..2790c57
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInPullProcessor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.Map;
+import org.apache.camel.Processor;
+import org.apache.camel.Exchange;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserSetStatusInPullProcessor implements Processor {
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Map.Entry<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
+
+        Boolean enabled = exchange.getProperty("enabled", Boolean.class);
+        Long key = exchange.getProperty("key", Long.class);
+
+        if (enabled != null) {
+            User user = userDAO.find(key);
+
+            WorkflowResult<Long> enableUpdate = null;
+            if (user.isSuspended() == null) {
+                enableUpdate = uwfAdapter.activate(key, null);
+            } else if (enabled && user.isSuspended()) {
+                enableUpdate = uwfAdapter.reactivate(key);
+            } else if (!enabled && !user.isSuspended()) {
+                enableUpdate = uwfAdapter.suspend(key);
+            }
+
+            if (enableUpdate != null) {
+                if (enableUpdate.getPropByRes() != null) {
+                    updated.getPropByRes().merge(enableUpdate.getPropByRes());
+                    updated.getPropByRes().purge();
+                }
+                updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
deleted file mode 100644
index ead8d4f..0000000
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
+++ /dev/null
@@ -1,70 +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.camel.processor;
-
-import java.util.Map;
-import org.apache.camel.Processor;
-import org.apache.camel.Exchange;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class UserSetStatusInSyncProcessor implements Processor {
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected UserWorkflowAdapter uwfAdapter;
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void process(final Exchange exchange) {
-        WorkflowResult<Map.Entry<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
-
-        Boolean enabled = exchange.getProperty("enabled", Boolean.class);
-        Long key = exchange.getProperty("key", Long.class);
-
-        if (enabled != null) {
-            User user = userDAO.find(key);
-
-            WorkflowResult<Long> enableUpdate = null;
-            if (user.isSuspended() == null) {
-                enableUpdate = uwfAdapter.activate(key, null);
-            } else if (enabled && user.isSuspended()) {
-                enableUpdate = uwfAdapter.reactivate(key);
-            } else if (!enabled && !user.isSuspended()) {
-                enableUpdate = uwfAdapter.suspend(key);
-            }
-
-            if (enableUpdate != null) {
-                if (enableUpdate.getPropByRes() != null) {
-                    updated.getPropByRes().merge(enableUpdate.getPropByRes());
-                    updated.getPropByRes().purge();
-                }
-                updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInPullProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInPullProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInPullProcessor.java
new file mode 100644
index 0000000..f24db22
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInPullProcessor.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserUpdateInPullProcessor implements Processor {
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Pair<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+        Boolean nullPriorityAsync = exchange.getProperty("nullPriorityAsync", Boolean.class);
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+                updated, updated.getResult().getKey().getPassword() != null, excludedResources);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        taskExecutor.execute(tasks, propagationReporter, nullPriorityAsync);
+
+        exchange.getOut().setBody(new ImmutablePair<>(
+                updated.getResult().getKey().getKey(), propagationReporter.getStatuses()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
deleted file mode 100644
index 7c4d6e0..0000000
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
+++ /dev/null
@@ -1,66 +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.camel.processor;
-
-import java.util.List;
-import java.util.Set;
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class UserUpdateInSyncProcessor implements Processor {
-
-    private static final Logger LOG = LoggerFactory.getLogger(UserUpdateInSyncProcessor.class);
-
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    @Autowired
-    protected PropagationTaskExecutor taskExecutor;
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void process(final Exchange exchange) {
-        WorkflowResult<Pair<UserPatch, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
-        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
-        Boolean nullPriorityAsync = exchange.getProperty("nullPriorityAsync", Boolean.class);
-
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                updated, updated.getResult().getKey().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter =
-                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
-        taskExecutor.execute(tasks, propagationReporter, nullPriorityAsync);
-
-        exchange.getOut().setBody(new ImmutablePair<>(
-                updated.getResult().getKey().getKey(), propagationReporter.getStatuses()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
index 8e1b914..d7875dc 100644
--- a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
@@ -38,21 +38,21 @@ under the License.
     </doTry>
   </route> 
                
-  <route id="createGroupSync">
-    <from uri="direct:createGroupInSync"/>
+  <route id="createGroupPull">
+    <from uri="direct:createGroupInPull"/>
     <setProperty propertyName="any">
       <simple>${body}</simple>
     </setProperty>
     <doTry>
       <bean ref="gwfAdapter" method="create(${body})"/>
-      <process ref="groupCreateInSyncProcessor"/>
-      <to uri="direct:createGroupInSyncPort"/>
+      <process ref="groupCreateInPullProcessor"/>
+      <to uri="direct:createGroupInPullPort"/>
       <doCatch>        
         <exception>java.lang.RuntimeException</exception>
         <handled>
           <constant>false</constant>
         </handled>
-        <to uri="direct:createGroupInSyncPort"/>
+        <to uri="direct:createGroupInPullPort"/>
       </doCatch>
     </doTry>
   </route> 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
index cbf2902..e218b68 100644
--- a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
@@ -58,26 +58,26 @@ under the License.
     </doTry>
   </route>
                 
-  <route id="updateUserInSync">
-    <from uri="direct:updateUserInSync"/>            
+  <route id="updateUserInPull">
+    <from uri="direct:updateUserInPull"/>            
     <doTry>
       <bean ref="uwfAdapter" method="update(${body})"/>
-      <to uri="direct:userInSync"/>
+      <to uri="direct:userInPull"/>
       <doCatch>        
         <exception>java.lang.RuntimeException</exception>
         <handled>
           <constant>false</constant>
         </handled>
-        <to uri="direct:updateInSyncPort"/>
+        <to uri="direct:updateInPullPort"/>
       </doCatch>
     </doTry>
   </route>
         
-  <route id="userInSync">
-    <from uri="direct:userInSync"/>
-    <process ref="userSetStatusInSyncProcessor"/>
-    <process ref="userUpdateInSyncProcessor"/>
-    <to uri="direct:updateInSyncPort"/>
+  <route id="userInPull">
+    <from uri="direct:userInPull"/>
+    <process ref="userSetStatusInPullProcessor"/>
+    <process ref="userUpdateInPullProcessor"/>
+    <to uri="direct:updateInPullPort"/>
   </route>
   
   <route id="deleteUser">

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/build-tools/src/main/resources/content.ldif
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/content.ldif b/fit/build-tools/src/main/resources/content.ldif
index aa47af5..982728b 100644
--- a/fit/build-tools/src/main/resources/content.ldif
+++ b/fit/build-tools/src/main/resources/content.ldif
@@ -29,21 +29,21 @@ objectClass: groupOfUniqueNames
 objectClass: top
 cn: testLDAPGroup
 uniqueMember: uid=admin,ou=system
-uniqueMember: uid=syncFromLDAP,ou=People,o=isp
-owner: uid=syncFromLDAP,ou=People,o=isp
+uniqueMember: uid=pullFromLDAP,ou=People,o=isp
+owner: uid=pullFromLDAP,ou=People,o=isp
 
-DN: uid=syncFromLDAP,ou=People,o=isp
+DN: uid=pullFromLDAP,ou=People,o=isp
 objectClass: organizationalPerson
 objectClass: person
 objectClass: inetOrgPerson
 objectClass: top
-cn: syncFromLDAP
+cn: pullFromLDAP
 description: Active
-mail: syncFromLDAP@syncope.apache.org
+mail: pullFromLDAP@syncope.apache.org
 sn: Surname
-uid: syncFromLDAP
+uid: pullFromLDAP
 userpassword:: cGFzc3dvcmQxMjM=
-givenname: syncFromLDAP
+givenname: pullFromLDAP
 registeredAddress:  5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8
 jpegPhoto:: /9j/4AAQSkZJRgABAQEBKwErAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoH
  BwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQk

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/build-tools/src/main/resources/testdb.sql
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql
index 03f9f96..0bbab3e 100644
--- a/fit/build-tools/src/main/resources/testdb.sql
+++ b/fit/build-tools/src/main/resources/testdb.sql
@@ -36,14 +36,14 @@ INSERT INTO test2 VALUES ('rossini', 'password321', 'true');
 INSERT INTO test2 VALUES ('verdi', 'password321', 'true');
 
 -- this table is for issueSYNCOPE230
-DROP TABLE testsync IF EXISTS;
-CREATE TABLE testsync (
+DROP TABLE testpull IF EXISTS;
+CREATE TABLE testpull (
 id NUMBER(10) PRIMARY KEY,
 username VARCHAR(80),
 surname VARCHAR(80),
 email VARCHAR(80));
 
-INSERT INTO testsync VALUES (965, 'issuesyncope230', 'Surname', 'syncope230@syncope.apache.org');
+INSERT INTO testpull VALUES (965, 'issuesyncope230', 'Surname', 'syncope230@syncope.apache.org');
 
 DROP TABLE testPRINTER IF EXISTS;
 CREATE TABLE testPRINTER (

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
index c620541..3d79fda 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
@@ -41,9 +41,9 @@ public class PrefixMappingItemTransformer extends DefaultMappingItemTransformer
     }
 
     @Override
-    public List<Object> beforeSync(final List<Object> values) {
+    public List<Object> beforePull(final List<Object> values) {
         if (values == null || values.isEmpty() || values.get(0) == null) {
-            return super.beforeSync(values);
+            return super.beforePull(values);
         } else {
             List<Object> newValues = new ArrayList<>(values);
             newValues.set(0, StringUtils.substringAfter(values.get(0).toString(), PREFIX));

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
new file mode 100644
index 0000000..81624f1
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.java.pushpull.DefaultPullActions;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+/**
+ * Test pull action.
+ */
+public class TestPullActions extends DefaultPullActions {
+
+    private int counter = 0;
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        AttrTO attrTO = null;
+        for (int i = 0; i < any.getPlainAttrs().size(); i++) {
+            AttrTO plainAttr = IterableUtils.get(any.getPlainAttrs(), i);
+            if ("fullname".equals(plainAttr.getSchema())) {
+                attrTO = plainAttr;
+            }
+        }
+        if (attrTO == null) {
+            attrTO = new AttrTO();
+            attrTO.setSchema("fullname");
+            any.getPlainAttrs().add(attrTO);
+        }
+        attrTO.getValues().clear();
+        attrTO.getValues().add(String.valueOf(counter++));
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeAssign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        if (any instanceof UserTO && "test2".equals(UserTO.class.cast(any).getUsername())) {
+            throw new IgnoreProvisionException();
+        }
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final M anyPatch) throws JobExecutionException {
+
+        AttrPatch fullnamePatch = null;
+        for (AttrPatch attrPatch : anyPatch.getPlainAttrs()) {
+            if ("fullname".equals(attrPatch.getAttrTO().getSchema())) {
+                fullnamePatch = attrPatch;
+            }
+        }
+        if (fullnamePatch == null) {
+            fullnamePatch = new AttrPatch.Builder().
+                    operation(PatchOperation.ADD_REPLACE).
+                    attrTO(new AttrTO.Builder().schema("fullname").build()).
+                    build();
+        }
+
+        fullnamePatch.getAttrTO().getValues().clear();
+        fullnamePatch.getAttrTO().getValues().add(String.valueOf(counter++));
+
+        return delta;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullRule.java
new file mode 100644
index 0000000..71d36a7
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullRule.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+
+/**
+ * Test pull rule relying on <tt>email</tt> attribute value.
+ */
+public class TestPullRule implements PullCorrelationRule {
+
+    @Override
+    public SearchCond getSearchCond(final ConnectorObject connObj) {
+        AttributeCond cond = new AttributeCond();
+        cond.setSchema("email");
+        cond.setType(AttributeCond.Type.EQ);
+        cond.setExpression(connObj.getName().getNameValue());
+
+        return SearchCond.getLeafCond(cond);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
index 1603083..05beee2 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import org.apache.syncope.core.provisioning.java.syncpull.DefaultReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.java.pushpull.DefaultReconciliationFilterBuilder;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.filter.Filter;
 import org.identityconnectors.framework.common.objects.filter.FilterBuilder;

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
deleted file mode 100644
index 19b172f..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core.reference;
-
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.java.syncpull.DefaultSyncActions;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-/**
- * Test synchronization action.
- */
-public class TestSyncActions extends DefaultSyncActions {
-
-    private int counter = 0;
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        AttrTO attrTO = null;
-        for (int i = 0; i < any.getPlainAttrs().size(); i++) {
-            AttrTO plainAttr = IterableUtils.get(any.getPlainAttrs(), i);
-            if ("fullname".equals(plainAttr.getSchema())) {
-                attrTO = plainAttr;
-            }
-        }
-        if (attrTO == null) {
-            attrTO = new AttrTO();
-            attrTO.setSchema("fullname");
-            any.getPlainAttrs().add(attrTO);
-        }
-        attrTO.getValues().clear();
-        attrTO.getValues().add(String.valueOf(counter++));
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeAssign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        if (any instanceof UserTO && "test2".equals(UserTO.class.cast(any).getUsername())) {
-            throw new IgnoreProvisionException();
-        }
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final M anyPatch) throws JobExecutionException {
-
-        AttrPatch fullnamePatch = null;
-        for (AttrPatch attrPatch : anyPatch.getPlainAttrs()) {
-            if ("fullname".equals(attrPatch.getAttrTO().getSchema())) {
-                fullnamePatch = attrPatch;
-            }
-        }
-        if (fullnamePatch == null) {
-            fullnamePatch = new AttrPatch.Builder().
-                    operation(PatchOperation.ADD_REPLACE).
-                    attrTO(new AttrTO.Builder().schema("fullname").build()).
-                    build();
-        }
-
-        fullnamePatch.getAttrTO().getValues().clear();
-        fullnamePatch.getAttrTO().getValues().add(String.valueOf(counter++));
-
-        return delta;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
deleted file mode 100644
index 5a1624a..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core.reference;
-
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-
-/**
- * Test synchronization rule relying on <tt>email</tt> attribute value.
- */
-public class TestSyncRule implements SyncCorrelationRule {
-
-    @Override
-    public SearchCond getSearchCond(final ConnectorObject connObj) {
-        AttributeCond cond = new AttributeCond();
-        cond.setSchema("email");
-        cond.setType(AttributeCond.Type.EQ);
-        cond.setExpression(connObj.getName().getNameValue());
-
-        return SearchCond.getLeafCond(cond);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index a64bcb8..f71d3b9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -89,6 +89,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import static org.junit.Assert.assertNotNull;
+
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = { "classpath:testJDBCContext.xml" })
 public abstract class AbstractITCase {
@@ -115,7 +117,7 @@ public abstract class AbstractITCase {
 
     protected static final String RESOURCE_NAME_CSV = "resource-csv";
 
-    protected static final String RESOURCE_NAME_DBSYNC = "resource-db-sync";
+    protected static final String RESOURCE_NAME_DBPULL = "resource-db-pull";
 
     protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr";
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
index 5995146..0a78dd3 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/cli/CLIITCase.java
@@ -49,6 +49,10 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 @FixMethodOrder(MethodSorters.JVM)
 public class CLIITCase extends AbstractITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
index 49b6d21..28d43b9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
@@ -258,7 +258,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
     }
 
     @Test
-    public void executeSyncTask() {
+    public void executePullTask() {
         wicketTester.clickLink("body:topologyLI:topology");
         wicketTester.executeAjaxEvent("body:resources:2:resources:0:res", Constants.ON_CLICK);
         wicketTester.clickLink("body:toggle:togglePanelContainer:container:actions:propagation");

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
index c7a8ee3..f17f906 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
@@ -34,6 +34,8 @@ import org.apache.wicket.util.visit.IVisitor;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.junit.Assert.assertNotNull;
+
 public class LogsITCase extends AbstractConsoleITCase {
 
     private final static String CONTAINER_PATH = "body:content:tabbedPanel:panel:loggerContainer";

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
index 389a7be..da1b6af 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
@@ -30,6 +30,8 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
+import static org.junit.Assert.assertNotNull;
+
 @FixMethodOrder(MethodSorters.JVM)
 public class ParametersITCase extends AbstractConsoleITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
index 5a1c851..7c5e497 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
@@ -29,6 +29,8 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
+import static org.junit.Assert.assertNull;
+
 @FixMethodOrder(MethodSorters.JVM)
 public class RolesITCase extends AbstractConsoleITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
index a3bb92d..62501be 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
@@ -31,6 +31,9 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 @FixMethodOrder(MethodSorters.JVM)
 public class SecurityQuestionsITCase extends AbstractConsoleITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
index 0c41d5b..c9f013b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
@@ -48,7 +48,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:delete", AjaxLink.class);
         wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:edit", AjaxLink.class);
         wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:propagation", AjaxLink.class);
-        wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:synchronization",
+        wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:pull",
                 AjaxLink.class);
         wicketTester.assertComponent("body:toggle:togglePanelContainer:container:actions:push", AjaxLink.class);
         wicketTester.executeAjaxEvent("body:syncope", Constants.ON_CLICK);
@@ -60,10 +60,10 @@ public class TopologyITCase extends AbstractConsoleITCase {
     }
 
     @Test
-    public void executeSyncTask() {
+    public void executePullTask() {
         wicketTester.clickLink("body:topologyLI:topology");
         wicketTester.executeAjaxEvent("body:resources:2:resources:0:res", Constants.ON_CLICK);
-        wicketTester.clickLink("body:toggle:togglePanelContainer:container:actions:synchronization");
+        wicketTester.clickLink("body:toggle:togglePanelContainer:container:actions:pull");
         wicketTester.clickLink("body:toggle:outerObjectsRepeater:1:outer:form:content:tasks:firstLevelContainer:"
                 + "first:container:content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable:"
                 + "body:rows:1:cells:10:cell:panelExecute:executeLink");

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
index 00ce952..82ed255 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java
@@ -47,7 +47,7 @@ import org.apache.syncope.fit.AbstractITCase;
 
 public abstract class AbstractTaskITCase extends AbstractITCase {
 
-    protected static final Long SYNC_TASK_ID = 4L;
+    protected static final Long PULL_TASK_ID = 4L;
 
     protected static final Long SCHED_TASK_ID = 5L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
index 8e825ea..f047593 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java
@@ -174,7 +174,7 @@ public class LoggerITCase extends AbstractITCase {
         for (EventCategoryTO eventCategoryTO : events) {
             if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
                 if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
-                        && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
+                        && EventCategoryType.PULL == eventCategoryTO.getType()) {
                     assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
                     assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
                     assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
@@ -210,7 +210,7 @@ public class LoggerITCase extends AbstractITCase {
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
             if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SyncJobDelegate".equals(eventCategoryTO.getCategory())) {
+                    && "PullJobDelegate".equals(eventCategoryTO.getCategory())) {
                 found = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
index bfbf63d..2a44c3d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -49,7 +49,7 @@ import org.apache.syncope.common.lib.types.LoggerType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
@@ -133,7 +133,7 @@ public class MultitenancyITCase extends AbstractITCase {
     }
 
     @Test
-    public void createResourceAndSync() {
+    public void createResourceAndPull() {
         // read connector
         ConnInstanceTO conn = adminClient.getService(ConnectorService.class).read(100L, Locale.ENGLISH.getLanguage());
         assertNotNull(conn);
@@ -188,13 +188,13 @@ public class MultitenancyITCase extends AbstractITCase {
         resource = adminClient.getService(ResourceService.class).read(resource.getKey());
         assertNotNull(resource);
 
-        // create sync task
-        SyncTaskTO task = new SyncTaskTO();
-        task.setName("LDAP Sync Task");
+        // create pull task
+        PullTaskTO task = new PullTaskTO();
+        task.setName("LDAP Pull Task");
         task.setActive(true);
         task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
         task.setResource(resource.getKey());
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
         task.setPerformCreate(true);
 
         response = adminClient.getService(TaskService.class).create(task);
@@ -203,7 +203,7 @@ public class MultitenancyITCase extends AbstractITCase {
                 Long.valueOf(StringUtils.substringAfterLast(response.getLocation().toASCIIString(), "/")), true);
         assertNotNull(resource);
 
-        // synchronize
+        // pull
         ExecTO execution = AbstractTaskITCase.execProvisioningTask(
                 adminClient.getService(TaskService.class), task.getKey(), 50, false);
 
@@ -212,10 +212,10 @@ public class MultitenancyITCase extends AbstractITCase {
         assertNotNull(status);
         assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(status));
 
-        // verify that synchronized user is found
+        // verify that pulled user is found
         PagedResult<UserTO> matchingUsers = adminClient.getService(UserService.class).search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("pullFromLDAP").query()).
                 build());
         assertNotNull(matchingUsers);
         assertEquals(1, matchingUsers.getResult().size());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
index cf7f335..10f0f56 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
@@ -31,15 +31,15 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
 import org.apache.syncope.fit.AbstractITCase;
-import org.apache.syncope.fit.core.reference.TestSyncRule;
+import org.apache.syncope.fit.core.reference.TestPullRule;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -47,21 +47,21 @@ import org.junit.runners.MethodSorters;
 @FixMethodOrder(MethodSorters.JVM)
 public class PolicyITCase extends AbstractITCase {
 
-    private SyncPolicyTO buildSyncPolicyTO() {
-        SyncPolicyTO policy = new SyncPolicyTO();
+    private PullPolicyTO buildPullPolicyTO() {
+        PullPolicyTO policy = new PullPolicyTO();
 
-        SyncPolicySpec spec = new SyncPolicySpec();
-        spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
+        PullPolicySpec spec = new PullPolicySpec();
+        spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestPullRule.class.getName());
 
         policy.setSpecification(spec);
-        policy.setDescription("Sync policy");
+        policy.setDescription("Pull policy");
 
         return policy;
     }
 
     @Test
     public void listByType() {
-        List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
+        List<PullPolicyTO> policyTOs = policyService.list(PolicyType.PULL);
 
         assertNotNull(policyTOs);
         assertFalse(policyTOs.isEmpty());
@@ -86,8 +86,8 @@ public class PolicyITCase extends AbstractITCase {
     }
 
     @Test
-    public void getSyncPolicy() {
-        SyncPolicyTO policyTO = policyService.read(1L);
+    public void getPullPolicy() {
+        PullPolicyTO policyTO = policyService.read(1L);
 
         assertNotNull(policyTO);
         assertTrue(policyTO.getUsedByRealms().isEmpty());
@@ -95,8 +95,8 @@ public class PolicyITCase extends AbstractITCase {
 
     @Test
     public void createMissingDescription() {
-        SyncPolicyTO policy = new SyncPolicyTO();
-        policy.setSpecification(new SyncPolicySpec());
+        PullPolicyTO policy = new PullPolicyTO();
+        policy.setSpecification(new PullPolicySpec());
 
         try {
             createPolicy(policy);
@@ -108,13 +108,13 @@ public class PolicyITCase extends AbstractITCase {
 
     @Test
     public void create() {
-        SyncPolicyTO policy = buildSyncPolicyTO();
+        PullPolicyTO policy = buildPullPolicyTO();
 
-        SyncPolicyTO policyTO = createPolicy(policy);
+        PullPolicyTO policyTO = createPolicy(policy);
 
         assertNotNull(policyTO);
-        assertEquals(PolicyType.SYNC, policyTO.getType());
-        assertEquals(TestSyncRule.class.getName(),
+        assertEquals(PolicyType.PULL, policyTO.getType());
+        assertEquals(TestPullRule.class.getName(),
                 policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name()));
     }
 
@@ -144,9 +144,9 @@ public class PolicyITCase extends AbstractITCase {
 
     @Test
     public void delete() {
-        SyncPolicyTO policy = buildSyncPolicyTO();
+        PullPolicyTO policy = buildPullPolicyTO();
 
-        SyncPolicyTO policyTO = createPolicy(policy);
+        PullPolicyTO policyTO = createPolicy(policy);
         assertNotNull(policyTO);
 
         policyService.delete(policyTO.getKey());
@@ -161,7 +161,7 @@ public class PolicyITCase extends AbstractITCase {
 
     @Test
     public void getCorrelationRules() {
-        assertEquals(2, syncopeService.platform().getSyncCorrelationRules().size());
+        assertEquals(2, syncopeService.platform().getPullCorrelationRules().size());
     }
 
     @Test


[10/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 02f9529..805bc4c 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -106,13 +106,13 @@ under the License.
                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
   
   <!-- sample policies -->
-  <SyncPolicy id="1" description="a sync policy" type="SYNC" 
+  <PullPolicy id="1" description="a pull policy" type="PULL" 
               specification='{"conflictResolutionAction":"IGNORE"'/>
   <PasswordPolicy id="2" description="a password policy" type="PASSWORD" 
                   historyLength="1" allowNullPassword="1"/> 
   <PasswordRuleConfInstance id="2" passwordPolicy_id="2"
                             serializedInstance='{"@class":"org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf","maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
-  <SyncPolicy id="3" description="sync policy 2" type="SYNC" 
+  <PullPolicy id="3" description="pull policy 2" type="PULL" 
               specification='{"conflictResolutionAction":"ALL","correlationRules":{"USER":"[\"username\",\"firstname\"]"}}'/>
   <PasswordPolicy id="4" description="sample password policy" type="PASSWORD"
                   historyLength="0"  allowNullPassword="1"/> 
@@ -126,13 +126,13 @@ under the License.
                  propagateSuspension="0" maxAuthenticationAttempts="3"/>
   <AccountRuleConfInstance id="6" accountPolicy_id="6"
                            serializedInstance='{"@class":"org.apache.syncope.common.lib.policy.DefaultAccountRuleConf","maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
-  <SyncPolicy id="7" description="sync policy 1" type="SYNC" 
+  <PullPolicy id="7" description="pull policy 1" type="PULL" 
               specification='{"conflictResolutionAction":"IGNORE"}'/>
   <PasswordPolicy id="8" description="sample password policy" type="PASSWORD"
                   historyLength="0" allowNullPassword="0"/> 
   <PasswordRuleConfInstance id="8" passwordPolicy_id="8"
                             serializedInstance='{"@class":"org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf","maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
-  <SyncPolicy id="9" description="sync policy for java rule" type="SYNC" 
+  <PullPolicy id="9" description="pull policy for java rule" type="PULL" 
               specification='{"conflictResolutionAction":"IGNORE"}'/>
 
   <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
@@ -565,8 +565,8 @@ under the License.
   <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
+                displayName="H2-testpull" version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Pull capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testpull"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="UPDATE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="DELETE"/>
@@ -585,117 +585,117 @@ under the License.
   
   <ExternalResource name="ws-target-resource-1" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin"
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-2" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" syncTraceLevel="ALL"
-                    syncPolicy_id="9"
+                    createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" pullTraceLevel="ALL"
+                    pullPolicy_id="9"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-timeout" connector_id="102"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    propagationPriority="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    propagationPriority="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/services/provisioning"]}]'
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-list-mappings-1" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-list-mappings-2" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-delete" connector_id="102"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-update" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="resource-testdb" connector_id="101"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="resource-testdb2" connector_id="106"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="resource-csv" connector_id="104"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    syncPolicy_id="3"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    pullPolicy_id="3"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-update-resetsynctoken" connector_id="100" enforceMandatoryCondition="1"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="resource-ldap" connector_id="105"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource_PropActions resource_name="resource-ldap"
                                 actionClassName="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/>
   <ExternalResource name="ws-target-resource-nopropagation" connector_id="103"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL" 
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL" 
                     passwordPolicy_id="4"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   
-  <!-- The following three resources have been added to verify the issue SYNCOPE-68 -->
+  <!-- The following three resources have been added to verify the issue PULLOPE-68 -->
   <ExternalResource name="ws-target-resource-nopropagation2" connector_id="103" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-nopropagation3" connector_id="103" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-nopropagation4" connector_id="103" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" pullTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
                     
-  <!-- External resource for issue SYNCOPE-230 -->
-  <ExternalResource name="resource-db-sync" connector_id="107"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+  <!-- External resource for issue PULLOPE-230 -->
+  <ExternalResource name="resource-db-pull" connector_id="107"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" pullTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0" 
                     overrideCapabilities="0"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
                     
-  <!-- External resource for issue SYNCOPE-267 -->
+  <!-- External resource for issue PULLOPE-267 -->
   <ExternalResource name="resource-db-virattr" connector_id="107"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" pullTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0" 
                     overrideCapabilities="0"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
   <ExternalResource name="resource-db-scripted" connector_id="108"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" pullTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0"
                     overrideCapabilities="0"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
-  <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
+  <!-- Use resource-testdb for passthrough authentication (PULLOPE-164) -->
   <AccountPolicy_ExternalResource accountPolicy_id="5" resource_name="resource-testdb"/>
     
   <SyncopeUser_ExternalResource user_id="1" resource_name="resource-testdb2"/>
@@ -844,10 +844,10 @@ under the License.
                connObjectKey="0" password="0" purpose="BOTH"/>
   <MappingItem id="205" extAttrName="email" mapping_id="9"
                intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="SYNCHRONIZATION"/>
+               connObjectKey="0" password="0" purpose="PULL"/>
   <MappingItem id="206" extAttrName="email" mapping_id="9"
                intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="SYNCHRONIZATION"/>
+               connObjectKey="0" password="0" purpose="PULL"/>
   <MappingItem id="207" extAttrName="__NAME__" mapping_id="9"
                intAttrName="csvuserid" intMappingType="UserDerivedSchema" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
@@ -920,7 +920,7 @@ under the License.
   
   <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group" provision_id="20" extAttrName="businessCategory"/>
 
-  <Provision id="16" resource_name="resource-db-sync" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Provision id="16" resource_name="resource-db-pull" anyType_name="USER" objectClass="__ACCOUNT__"/>
   <Mapping id="16" provision_id="16"/>
   <MappingItem id="322" connObjectKey="0" mapping_id="16"
                extAttrName="EMAIL" intAttrName="email" intMappingType="UserPlainSchema" 
@@ -980,12 +980,12 @@ under the License.
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="3" operation="DELETE"
         objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1"
         attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"type","value":["type"]}]'/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        syncMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE" active="1"/>
-  <AnyTemplateSyncTask id="41" syncTask_id="4" anyType_name="USER"
+  <Task DTYPE="PullTask" type="PULL" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"
+        pullMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE" active="1"/>
+  <AnyTemplatePullTask id="41" pullTask_id="4" anyType_name="USER"
                        template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":8,"groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}]}'/>
-  <AnyTemplateSyncTask id="42" syncTask_id="4" anyType_name="GROUP"
+  <AnyTemplatePullTask id="42" pullTask_id="4" anyType_name="GROUP"
                        template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[]}'/>
   <Task DTYPE="SchedTask" type="SCHEDULED" id="5" name="SampleJob Task"  active="1"
         jobDelegateClassName="org.apache.syncope.fit.core.reference.TestSampleJobDelegate" cronExpression="0 0 0 1 * ?"/>
@@ -993,105 +993,105 @@ under the License.
         objectClassName="__ACCOUNT__" resource_name="ws-target-resource-nopropagation" anyTypeKind="USER" anyKey="1"
         attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
   <TaskExec id="6" task_id="6" start="2015-12-17 09:40:00.506" end="2015-12-17 09:42:00.506" status="SUCCESS"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="7" name="TestDB Task" resource_name="resource-testdb"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION"
+  <Task DTYPE="PullTask" type="PULL" id="7" name="TestDB Task" resource_name="resource-testdb"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" pullStatus="1" pullMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
-  <AnyTemplateSyncTask id="71" syncTask_id="7" anyType_name="USER"
+  <AnyTemplatePullTask id="71" pullTask_id="7" anyType_name="USER"
                        template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"relationships":[],"memberships":[],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","readonly":false,"values":["&apos;type a&apos;"]},{"schema":"userId","readonly":false,"values":["&apos;reconciled@syncope.apache.org&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;reconciled fullname&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;surname&apos;"]}]}'/>
-  <AnyTemplateSyncTask id="72" syncTask_id="7" anyType_name="GROUP"
+  <AnyTemplatePullTask id="72" pullTask_id="7" anyType_name="GROUP"
                        template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[]}'/>
-  <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-81" 
+  <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="admin@prova.org" subject="Notification for PULLOPE-81" 
         textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="9" name="TestDB2 Task" resource_name="resource-testdb2"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION"
+  <Task DTYPE="PullTask" type="PULL" id="9" name="TestDB2 Task" resource_name="resource-testdb2"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" pullStatus="1" pullMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="10" name="TestDB Sync Task" resource_name="resource-db-sync"
-        destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
+  <Task DTYPE="PullTask" type="PULL" id="10" name="TestDB Pull Task" resource_name="resource-db-pull"
+        destinationRealm_id="1" pullMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" pullStatus="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="11" name="LDAP Sync Task" resource_name="resource-ldap"
-        destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
+  <Task DTYPE="PullTask" type="PULL" id="11" name="LDAP Pull Task" resource_name="resource-ldap"
+        destinationRealm_id="1" pullMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" pullStatus="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
-  <AnyTemplateSyncTask id="1" syncTask_id="11" anyType_name="USER"
+  <AnyTemplatePullTask id="1" pullTask_id="11" anyType_name="USER"
                        template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/>
-  <AnyTemplateSyncTask id="2" syncTask_id="11" anyType_name="GROUP"
+  <AnyTemplatePullTask id="2" pullTask_id="11" anyType_name="GROUP"
                        template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
-  <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.syncpull.LDAPMembershipSyncActions"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="12" name="VirAttrCache test" resource_name="resource-csv"
-        destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" syncMode="FULL_RECONCILIATION"
+  <PullTask_actionsClassNames PullTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.pushpull.LDAPMembershipPullActions"/>
+  <Task DTYPE="PullTask" type="PULL" id="12" name="VirAttrCache test" resource_name="resource-csv"
+        destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" pullStatus="0" pullMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
   <Task DTYPE="PushTask" type="PUSH" id="13" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"         
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"         
         unmatchingRule="ASSIGN" matchingRule="IGNORE" active="1"/>  
   <PushTaskAnyFilter id="131" anyType_name="USER" pushTask_id="13" fiql="surname==Vivaldi"/>
   <PushTaskAnyFilter id="132" anyType_name="GROUP" pushTask_id="13" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="14" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"         
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"         
         unmatchingRule="PROVISION" matchingRule="IGNORE" active="1"/>
   <PushTaskAnyFilter id="141" anyType_name="USER" pushTask_id="14" fiql="surname==Bellini"/>
   <PushTaskAnyFilter id="142" anyType_name="GROUP" pushTask_id="14" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="15" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="UNLINK" matchingRule="IGNORE" active="1"/>
   <PushTaskAnyFilter id="151" anyType_name="USER" pushTask_id="15" fiql="surname==Puccini"/>
   <PushTaskAnyFilter id="152" anyType_name="GROUP" pushTask_id="15" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="16" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"         
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"         
         unmatchingRule="IGNORE" matchingRule="IGNORE" active="1"/>
   <PushTaskAnyFilter id="161" anyType_name="USER" pushTask_id="16" fiql="surname==Verdi"/>
   <PushTaskAnyFilter id="162" anyType_name="GROUP" pushTask_id="16" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="17" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="ASSIGN" matchingRule="UPDATE" active="1"/>
   <PushTaskAnyFilter id="171" anyType_name="USER" pushTask_id="17" fiql="username==_NO_ONE_"/>
   <PushTaskAnyFilter id="172" anyType_name="GROUP" pushTask_id="17" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="18" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="IGNORE" matchingRule="DEPROVISION" active="1"/>
   <PushTaskAnyFilter id="181" anyType_name="USER" pushTask_id="18" fiql="surname==Verdi"/>
   <PushTaskAnyFilter id="182" anyType_name="GROUP" pushTask_id="18" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="19" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="IGNORE" matchingRule="UNASSIGN" active="1"/>
   <PushTaskAnyFilter id="191" anyType_name="USER" pushTask_id="19" fiql="surname==Rossini"/>
   <PushTaskAnyFilter id="192" anyType_name="GROUP" pushTask_id="19" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="20" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="IGNORE" matchingRule="LINK" active="1"/>
   <PushTaskAnyFilter id="201" anyType_name="USER" pushTask_id="20" fiql="surname==Verdi"/>
   <PushTaskAnyFilter id="202" anyType_name="GROUP" pushTask_id="20" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="21" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="IGNORE" matchingRule="UNLINK" active="1"/>
   <PushTaskAnyFilter id="211" anyType_name="USER" pushTask_id="21" fiql="surname==Verdi"/>
   <PushTaskAnyFilter id="212" anyType_name="GROUP" pushTask_id="21" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="22" name="Export on resource-testdb2" resource_name="resource-testdb2"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="IGNORE" matchingRule="UPDATE"  active="1"/>
   <PushTaskAnyFilter id="221" anyType_name="USER" pushTask_id="22" fiql="surname==Verdi"/>
   <PushTaskAnyFilter id="222" anyType_name="GROUP" pushTask_id="22" fiql="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="23" name="Export on resource-ldap" resource_name="resource-ldap"
-        performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"        
+        performCreate="1" performUpdate="1" performDelete="1" pullStatus="1"        
         unmatchingRule="ASSIGN" matchingRule="UNLINK" active="1"/>
   <PushTaskAnyFilter id="231" anyType_name="USER" pushTask_id="23" fiql="username==_NO_ONE_"/>
   <PushTaskAnyFilter id="232" anyType_name="GROUP" pushTask_id="23" fiql="name==citizen"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="24" name="CSV Task (update matching; provision unmatching)" resource_name="resource-csv"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
+  <Task DTYPE="PullTask" type="PULL" id="24" name="CSV Task (update matching; provision unmatching)" resource_name="resource-csv"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" pullStatus="1" pullMode="INCREMENTAL"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
-  <AnyTemplateSyncTask id="3" syncTask_id="24" anyType_name="USER"
+  <AnyTemplatePullTask id="3" pullTask_id="24" anyType_name="USER"
                        template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[{"schema":"firstname","readonly":false,"values":[""]},{"schema":"userId","readonly":false,"values":["&apos;test&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;test&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;test&apos;"]}]}'/>
-  <AnyTemplateSyncTask id="4" syncTask_id="24" anyType_name="GROUP"
+  <AnyTemplatePullTask id="4" pullTask_id="24" anyType_name="GROUP"
                        template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[]}'/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
+  <Task DTYPE="PullTask" type="PULL" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" pullStatus="1" pullMode="INCREMENTAL"
         unmatchingRule="IGNORE" matchingRule="UNLINK" active="1"/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="26" name="CSV (ignore matching; assign unmatching)" resource_name="resource-csv"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
+  <Task DTYPE="PullTask" type="PULL" id="26" name="CSV (ignore matching; assign unmatching)" resource_name="resource-csv"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" pullStatus="1" pullMode="INCREMENTAL"
         unmatchingRule="ASSIGN" matchingRule="IGNORE" active="1"/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" operation="CREATE"
         objectClassName="__ACCOUNT__" resource_name="resource-testdb" anyTypeKind="USER" anyKey="1"
         attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
-  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="28" name="Scripted SQL" resource_name="resource-db-scripted"
-        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" syncMode="INCREMENTAL"
+  <Task DTYPE="PullTask" type="PULL" id="28" name="Scripted SQL" resource_name="resource-db-scripted"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" pullStatus="0" pullMode="INCREMENTAL"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
 
   <MailTemplate name="requestPasswordReset"

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
index b637508..c54cf71 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
@@ -34,7 +34,7 @@ import org.identityconnectors.framework.common.objects.SyncResultsHandler;
 import org.identityconnectors.framework.common.objects.SyncToken;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.identityconnectors.framework.common.objects.filter.Filter;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
 
 /**
  * Entry point for making requests on underlying connector bundles.

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/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 cf198fe..37db510 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
@@ -26,7 +26,7 @@ import org.apache.syncope.common.lib.patch.StatusPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserPatch> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
index ae11199..18d998b 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
@@ -22,7 +22,7 @@ import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 
 /**
- * Transforms values to be propagated to (or synchronizing from) external resources right before they leave (or enter)
+ * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter)
  * the Syncope internal storage.
  *
  * These transformations are not applied to virtual attribute values.
@@ -38,10 +38,10 @@ public interface MappingItemTransformer {
     List<PlainAttrValue> beforePropagation(List<PlainAttrValue> values);
 
     /**
-     * Invoked while reading attribute values from external resource during synchronization.
+     * Invoked while reading attribute values from external resource during pull.
      *
      * @param values original values
      * @return transformed values
      */
-    List<Object> beforeSync(List<Object> values);
+    List<Object> beforePull(List<Object> values);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPullResultHandler.java
new file mode 100644
index 0000000..db7eb81
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPullResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.pushpull;
+
+public interface AnyObjectPullResultHandler extends SyncopePullResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPushResultHandler.java
new file mode 100644
index 0000000..8775e7e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/AnyObjectPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.pushpull;
+
+public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPullResultHandler.java
new file mode 100644
index 0000000..247c583
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPullResultHandler.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.pushpull;
+
+import java.util.Map;
+
+public interface GroupPullResultHandler extends SyncopePullResultHandler {
+
+    Map<Long, String> getGroupOwnerMap();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPushResultHandler.java
new file mode 100644
index 0000000..a080022
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/GroupPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.pushpull;
+
+public interface GroupPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/IgnoreProvisionException.java
new file mode 100644
index 0000000..bf56246
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/IgnoreProvisionException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.pushpull;
+
+/**
+ * Raised by {@link PullActions} or {@link PushActions} methods when the given any object is to be ignored for
+ * pull / push.
+ */
+public class IgnoreProvisionException extends RuntimeException {
+
+    private static final long serialVersionUID = -8803817097998786364L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java
new file mode 100644
index 0000000..1470ac1
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java
@@ -0,0 +1,40 @@
+/*
+ * 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.pushpull;
+
+import org.quartz.JobExecutionException;
+
+public interface ProvisioningActions {
+
+    /**
+     * Action to be executed before to start the provisioning (push / pull) task execution.
+     *
+     * @param profile provisioning profile
+     * @throws JobExecutionException in case of generic failure
+     */
+    void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
+
+    /**
+     * Action to be executed after the provisioning (push / pull) task completion.
+     *
+     * @param profile provisioning profile
+     * @throws JobExecutionException in case of generic failure
+     */
+    void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningProfile.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningProfile.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningProfile.java
new file mode 100644
index 0000000..517908d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningProfile.java
@@ -0,0 +1,81 @@
+/*
+ * 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.pushpull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.common.lib.types.ConflictResolutionAction;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+
+public class ProvisioningProfile<T extends ProvisioningTask, A extends ProvisioningActions> {
+
+    /**
+     * Syncing connector.
+     */
+    private final Connector connector;
+
+    private final T task;
+
+    private final List<ProvisioningReport> results = new ArrayList<>();
+
+    private boolean dryRun;
+
+    private ConflictResolutionAction resAct;
+
+    private final List<A> actions = new ArrayList<>();
+
+    public ProvisioningProfile(final Connector connector, final T task) {
+        this.connector = connector;
+        this.task = task;
+    }
+
+    public Connector getConnector() {
+        return connector;
+    }
+
+    public T getTask() {
+        return task;
+    }
+
+    public Collection<ProvisioningReport> getResults() {
+        return results;
+    }
+
+    public boolean isDryRun() {
+        return dryRun;
+    }
+
+    public void setDryRun(final boolean dryRun) {
+        this.dryRun = dryRun;
+    }
+
+    public ConflictResolutionAction getResAct() {
+        return resAct;
+    }
+
+    public void setResAct(final ConflictResolutionAction resAct) {
+        this.resAct = resAct;
+    }
+
+    public List<A> getActions() {
+        return actions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningReport.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningReport.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningReport.java
new file mode 100644
index 0000000..7fa0366
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningReport.java
@@ -0,0 +1,140 @@
+/*
+ * 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.pushpull;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.TraceLevel;
+
+public class ProvisioningReport {
+
+    public enum Status {
+
+        SUCCESS,
+        IGNORE,
+        FAILURE
+
+    }
+
+    private String message;
+
+    private Status status;
+
+    private String anyType;
+
+    private ResourceOperation operation;
+
+    private Long key;
+
+    private String name;
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(final String message) {
+        this.message = message;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public Long getKey() {
+        return key;
+    }
+
+    public void setKey(final Long key) {
+        this.key = key;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(final Status status) {
+        this.status = status;
+    }
+
+    public String getAnyType() {
+        return anyType;
+    }
+
+    public void setAnyType(final String anyType) {
+        this.anyType = anyType;
+    }
+
+    public ResourceOperation getOperation() {
+        return operation;
+    }
+
+    public void setOperation(final ResourceOperation operation) {
+        this.operation = operation;
+    }
+
+    @Override
+    public String toString() {
+        return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
+    }
+
+    /**
+     * Human readable report string, using the given trace level.
+     *
+     * @param level trace level
+     * @return String for certain levels, null for level NONE
+     */
+    public String getReportString(final TraceLevel level) {
+        if (level == TraceLevel.SUMMARY) {
+            // No per entry log in this case.
+            return null;
+        } else if (level == TraceLevel.FAILURES && status == Status.FAILURE) {
+            // only report failures
+            return String.format("Failed %s (id/name): %d/%s with message: %s", operation, key, name, message);
+        } else {
+            // All
+            return String.format("%s %s (id/name): %d/%s %s", operation, status, key, name,
+                    StringUtils.isBlank(message)
+                    ? ""
+                    : "with message: " + message);
+        }
+    }
+
+    /**
+     * Helper method to invoke logging per provisioning result, for the given trace level.
+     *
+     * @param results provisioning results
+     * @param level trace level
+     * @return report as string
+     */
+    public static String produceReport(final Collection<ProvisioningReport> results, final TraceLevel level) {
+        StringBuilder sb = new StringBuilder();
+        for (ProvisioningReport result : results) {
+            sb.append(result.getReportString(level)).append('\n');
+        }
+        return sb.toString();
+    }
+}


[05/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
deleted file mode 100644
index 42762f2..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-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.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-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.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
-import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
-import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncopeSyncResultHandler;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(rollbackFor = Throwable.class)
-public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
-        implements SyncopeSyncResultHandler {
-
-    @Autowired
-    protected SyncUtils syncUtilities;
-
-    @Autowired
-    protected VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    protected VirAttrCache virAttrCache;
-
-    protected abstract String getName(AnyTO anyTO);
-
-    protected abstract ProvisioningManager<?, ?> getProvisioningManager();
-
-    protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningReport result);
-
-    protected AnyTO doLink(final AnyTO before, final boolean unlink) {
-        AnyPatch patch = newPatch(before.getKey());
-        patch.setKey(before.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        return getAnyTO(update(patch).getResult());
-    }
-
-    protected abstract AnyTO doUpdate(AnyTO before, AnyPatch anyPatch, SyncDelta delta, ProvisioningReport result);
-
-    protected void doDeprovision(final AnyTypeKind kind, final Long key, final boolean unlink) {
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-        taskExecutor.execute(propagationManager.getDeleteTasks(
-                kind,
-                key,
-                propByRes,
-                null));
-
-        if (unlink) {
-            AnyPatch anyObjectPatch = newPatch(key);
-            anyObjectPatch.getResources().add(new StringPatchItem.Builder().
-                    operation(PatchOperation.DELETE).
-                    value(profile.getTask().getResource().getKey()).build());
-        }
-    }
-
-    protected void doDelete(final AnyTypeKind kind, final Long key) {
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-        try {
-            taskExecutor.execute(propagationManager.getDeleteTasks(
-                    kind,
-                    key,
-                    propByRes,
-                    null));
-        } 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);
-        }
-
-        getProvisioningManager().delete(key, true);
-    }
-
-    @Override
-    public boolean handle(final SyncDelta delta) {
-        Provision provision = null;
-        try {
-            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) {
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.NONE);
-            result.setAnyType(provision == null
-                    ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
-            result.setStatus(ProvisioningReport.Status.IGNORE);
-            result.setKey(0L);
-            result.setName(delta.getObject().getName().getNameValue());
-            profile.getResults().add(result);
-
-            LOG.warn("Ignoring during synchronization", e);
-            return true;
-        } catch (JobExecutionException e) {
-            LOG.error("Synchronization failed", e);
-            return false;
-        }
-    }
-
-    protected List<ProvisioningReport> assign(
-            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
-            throws JobExecutionException {
-
-        if (!profile.getTask().isPerformCreate()) {
-            LOG.debug("SyncTask not configured for create");
-            return Collections.<ProvisioningReport>emptyList();
-        }
-
-        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
-        anyTO.getResources().add(profile.getTask().getResource().getKey());
-
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.CREATE);
-        result.setAnyType(provision.getAnyType().getKey());
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(getName(anyTO));
-
-        if (profile.isDryRun()) {
-            result.setKey(0L);
-        } else {
-            SyncDelta actionedDelta = delta;
-            for (SyncActions action : profile.getActions()) {
-                actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, anyTO);
-            }
-
-            create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
-        }
-
-        return Collections.singletonList(result);
-    }
-
-    protected List<ProvisioningReport> provision(
-            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
-            throws JobExecutionException {
-
-        if (!profile.getTask().isPerformCreate()) {
-            LOG.debug("SyncTask not configured for create");
-            return Collections.<ProvisioningReport>emptyList();
-        }
-
-        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.CREATE);
-        result.setAnyType(provision.getAnyType().getKey());
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(getName(anyTO));
-
-        if (profile.isDryRun()) {
-            result.setKey(0L);
-        } else {
-            SyncDelta actionedDelta = delta;
-            for (SyncActions action : profile.getActions()) {
-                actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, anyTO);
-            }
-
-            create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
-        }
-
-        return Collections.singletonList(result);
-    }
-
-    private void create(
-            final AnyTO anyTO,
-            final SyncDelta delta,
-            final String operation,
-            final ProvisioningReport result)
-            throws JobExecutionException {
-
-        Object output;
-        Result resultStatus;
-
-        try {
-            AnyTO actual = doCreate(anyTO, delta, result);
-            result.setName(getName(actual));
-            output = actual;
-            resultStatus = Result.SUCCESS;
-
-            for (SyncActions action : profile.getActions()) {
-                action.after(this.getProfile(), delta, actual, result);
-            }
-        } 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 {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
-            output = e;
-            resultStatus = Result.FAILURE;
-
-            for (SyncActions action : profile.getActions()) {
-                action.onError(this.getProfile(), delta, result, e);
-            }
-        } catch (Exception e) {
-            result.setStatus(ProvisioningReport.Status.FAILURE);
-            result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-            LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
-            output = e;
-            resultStatus = Result.FAILURE;
-
-            for (SyncActions action : profile.getActions()) {
-                action.onError(this.getProfile(), delta, result, e);
-            }
-        }
-
-        audit(operation, resultStatus, null, output, delta);
-    }
-
-    protected List<ProvisioningReport> 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.<ProvisioningReport>emptyList();
-        }
-
-        LOG.debug("About to update {}", anys);
-
-        List<ProvisioningReport> results = new ArrayList<>();
-
-        SyncDelta workingDelta = delta;
-        for (Long key : anys) {
-            LOG.debug("About to update {}", key);
-
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.UPDATE);
-            result.setAnyType(provision.getAnyType().getKey());
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
-            result.setKey(key);
-
-            AnyTO before = getAnyTO(key);
-            if (before == null) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
-            } else {
-                result.setName(getName(before));
-            }
-
-            Result resultStatus;
-            Object output;
-            if (!profile.isDryRun()) {
-                if (before == null) {
-                    resultStatus = Result.FAILURE;
-                    output = null;
-                } else {
-                    try {
-                        AnyPatch anyPatch = connObjectUtils.getAnyPatch(
-                                before.getKey(),
-                                workingDelta.getObject(),
-                                before,
-                                profile.getTask(),
-                                provision,
-                                getAnyUtils());
-
-                        for (SyncActions action : profile.getActions()) {
-                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyPatch);
-                        }
-
-                        AnyTO updated = doUpdate(before, anyPatch, workingDelta, result);
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), workingDelta, updated, result);
-                        }
-
-                        output = updated;
-                        resultStatus = Result.SUCCESS;
-                        result.setName(getName(updated));
-                        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 {} {}",
-                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), workingDelta, result, e);
-                        }
-                    } catch (Exception e) {
-                        result.setStatus(ProvisioningReport.Status.FAILURE);
-                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}",
-                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), workingDelta, result, e);
-                        }
-                    }
-                }
-                audit(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
-            }
-            results.add(result);
-        }
-        return results;
-    }
-
-    protected List<ProvisioningReport> deprovision(
-            final SyncDelta delta,
-            final List<Long> anys,
-            final Provision provision,
-            final boolean unlink)
-            throws JobExecutionException {
-
-        if (!profile.getTask().isPerformUpdate()) {
-            LOG.debug("SyncTask not configured for update");
-            return Collections.<ProvisioningReport>emptyList();
-        }
-
-        LOG.debug("About to update {}", anys);
-
-        final List<ProvisioningReport> updResults = new ArrayList<>();
-
-        for (Long key : anys) {
-            LOG.debug("About to unassign resource {}", key);
-
-            Object output;
-            Result resultStatus;
-
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.DELETE);
-            result.setAnyType(provision.getAnyType().getKey());
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
-            result.setKey(key);
-
-            AnyTO before = getAnyTO(key);
-
-            if (before == null) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
-            }
-
-            if (!profile.isDryRun()) {
-                if (before == null) {
-                    resultStatus = Result.FAILURE;
-                    output = null;
-                } else {
-                    result.setName(getName(before));
-
-                    try {
-                        if (unlink) {
-                            for (SyncActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), delta, before);
-                            }
-                        } else {
-                            for (SyncActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), delta, before);
-                            }
-                        }
-
-                        doDeprovision(provision.getAnyType().getKind(), key, unlink);
-                        output = getAnyTO(key);
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
-                        }
-
-                        resultStatus = Result.SUCCESS;
-                        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 {} {}",
-                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), delta, result, e);
-                        }
-                    } catch (Exception e) {
-                        result.setStatus(ProvisioningReport.Status.FAILURE);
-                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}",
-                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), delta, result, e);
-                        }
-                    }
-                }
-                audit(unlink
-                        ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
-                        : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
-            }
-            updResults.add(result);
-        }
-
-        return updResults;
-    }
-
-    protected List<ProvisioningReport> link(
-            final SyncDelta delta,
-            final List<Long> anys,
-            final Provision provision,
-            final boolean unlink)
-            throws JobExecutionException {
-
-        if (!profile.getTask().isPerformUpdate()) {
-            LOG.debug("SyncTask not configured for update");
-            return Collections.<ProvisioningReport>emptyList();
-        }
-
-        LOG.debug("About to update {}", anys);
-
-        final List<ProvisioningReport> updResults = new ArrayList<>();
-
-        for (Long key : anys) {
-            LOG.debug("About to unassign resource {}", key);
-
-            Object output;
-            Result resultStatus;
-
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.NONE);
-            result.setAnyType(provision.getAnyType().getKey());
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
-            result.setKey(key);
-
-            AnyTO before = getAnyTO(key);
-
-            if (before == null) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
-            }
-
-            if (!profile.isDryRun()) {
-                if (before == null) {
-                    resultStatus = Result.FAILURE;
-                    output = null;
-                } else {
-                    result.setName(getName(before));
-
-                    try {
-                        if (unlink) {
-                            for (SyncActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), delta, before);
-                            }
-                        } else {
-                            for (SyncActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), delta, before);
-                            }
-                        }
-
-                        output = doLink(before, unlink);
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
-                        }
-
-                        resultStatus = Result.SUCCESS;
-                        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 {} {}",
-                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), delta, result, e);
-                        }
-                    } catch (Exception e) {
-                        result.setStatus(ProvisioningReport.Status.FAILURE);
-                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}",
-                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
-                        output = e;
-                        resultStatus = Result.FAILURE;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), delta, result, e);
-                        }
-                    }
-                }
-                audit(unlink ? MatchingRule.toEventName(MatchingRule.UNLINK)
-                        : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
-            }
-            updResults.add(result);
-        }
-
-        return updResults;
-    }
-
-    protected List<ProvisioningReport> delete(
-            final SyncDelta delta,
-            final List<Long> anys,
-            final Provision provision)
-            throws JobExecutionException {
-
-        if (!profile.getTask().isPerformDelete()) {
-            LOG.debug("SyncTask not configured for delete");
-            return Collections.<ProvisioningReport>emptyList();
-        }
-
-        LOG.debug("About to delete {}", anys);
-
-        List<ProvisioningReport> delResults = new ArrayList<>();
-
-        SyncDelta workingDelta = delta;
-        for (Long key : anys) {
-            Object output;
-            Result resultStatus = Result.FAILURE;
-
-            ProvisioningReport result = new ProvisioningReport();
-
-            try {
-                AnyTO before = getAnyTO(key);
-
-                result.setKey(key);
-                result.setName(getName(before));
-                result.setOperation(ResourceOperation.DELETE);
-                result.setAnyType(provision.getAnyType().getKey());
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-
-                if (!profile.isDryRun()) {
-                    for (SyncActions action : profile.getActions()) {
-                        workingDelta = action.beforeDelete(this.getProfile(), workingDelta, before);
-                    }
-
-                    try {
-                        doDelete(provision.getAnyType().getKind(), key);
-                        output = null;
-                        resultStatus = Result.SUCCESS;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), workingDelta, before, result);
-                        }
-                    } catch (IgnoreProvisionException e) {
-                        throw e;
-                    } catch (Exception e) {
-                        result.setStatus(ProvisioningReport.Status.FAILURE);
-                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
-                        output = e;
-
-                        for (SyncActions action : profile.getActions()) {
-                            action.onError(this.getProfile(), workingDelta, result, e);
-                        }
-                    }
-
-                    audit(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
-                }
-
-                delResults.add(result);
-            } catch (NotFoundException e) {
-                LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
-            } catch (DelegatedAdministrationException e) {
-                LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), key, e);
-            } catch (Exception e) {
-                LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
-            }
-        }
-
-        return delResults;
-    }
-
-    private List<ProvisioningReport> ignore(
-            final SyncDelta delta,
-            final Provision provision,
-            final boolean matching)
-            throws JobExecutionException {
-
-        LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
-
-        final List<ProvisioningReport> ignoreResults = new ArrayList<>();
-        ProvisioningReport result = new ProvisioningReport();
-
-        result.setKey(null);
-        result.setName(delta.getObject().getUid().getUidValue());
-        result.setOperation(ResourceOperation.NONE);
-        result.setAnyType(provision.getAnyType().getKey());
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        ignoreResults.add(result);
-
-        if (!profile.isDryRun()) {
-            audit(matching
-                    ? MatchingRule.toEventName(MatchingRule.IGNORE)
-                    : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
-        }
-
-        return ignoreResults;
-    }
-
-    /**
-     * 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, final Provision provision) throws JobExecutionException {
-        AnyUtils anyUtils = getAnyUtils();
-
-        LOG.debug("Process {} for {} as {}",
-                delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
-        String uid = delta.getPreviousUid() == null
-                ? delta.getUid().getUidValue()
-                : delta.getPreviousUid().getUidValue();
-
-        try {
-            List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils);
-            LOG.debug("Match(es) found for {} as {}: {}",
-                    delta.getUid().getUidValue(), delta.getObject().getObjectClass(), anyKeys);
-
-            if (anyKeys.size() > 1) {
-                switch (profile.getResAct()) {
-                    case IGNORE:
-                        throw new IllegalStateException("More than one match " + anyKeys);
-
-                    case FIRSTMATCH:
-                        anyKeys = anyKeys.subList(0, 1);
-                        break;
-
-                    case LASTMATCH:
-                        anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
-                        break;
-
-                    default:
-                    // keep anyKeys unmodified
-                }
-            }
-
-            if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
-                if (anyKeys.isEmpty()) {
-                    switch (profile.getTask().getUnmatchingRule()) {
-                        case ASSIGN:
-                            profile.getResults().addAll(assign(delta, provision, anyUtils));
-                            break;
-
-                        case PROVISION:
-                            profile.getResults().addAll(provision(delta, provision, anyUtils));
-                            break;
-
-                        case IGNORE:
-                            profile.getResults().addAll(ignore(delta, provision, false));
-                            break;
-
-                        default:
-                        // do nothing
-                    }
-                } else {
-                    // update VirAttrCache
-                    for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
-                        Attribute attr = delta.getObject().getAttributeByName(virSchema.getExtAttrName());
-                        for (Long anyKey : anyKeys) {
-                            if (attr == null) {
-                                virAttrCache.expire(
-                                        provision.getAnyType().getKey(),
-                                        anyKey,
-                                        virSchema.getKey());
-                            } else {
-                                VirAttrCacheValue cacheValue = new VirAttrCacheValue();
-                                cacheValue.setValues(attr.getValue());
-                                virAttrCache.put(
-                                        provision.getAnyType().getKey(),
-                                        anyKey,
-                                        virSchema.getKey(),
-                                        cacheValue);
-                            }
-                        }
-                    }
-
-                    switch (profile.getTask().getMatchingRule()) {
-                        case UPDATE:
-                            profile.getResults().addAll(update(delta, anyKeys, provision));
-                            break;
-
-                        case DEPROVISION:
-                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
-                            break;
-
-                        case UNASSIGN:
-                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
-                            break;
-
-                        case LINK:
-                            profile.getResults().addAll(link(delta, anyKeys, provision, false));
-                            break;
-
-                        case UNLINK:
-                            profile.getResults().addAll(link(delta, anyKeys, provision, true));
-                            break;
-
-                        case IGNORE:
-                            profile.getResults().addAll(ignore(delta, provision, true));
-                            break;
-
-                        default:
-                        // do nothing
-                    }
-                }
-            } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
-                if (anyKeys.isEmpty()) {
-                    LOG.debug("No match found for deletion");
-                } else {
-                    profile.getResults().addAll(delete(delta, anyKeys, provision));
-                }
-            }
-        } catch (IllegalStateException | IllegalArgumentException e) {
-            LOG.warn(e.getMessage());
-        }
-    }
-
-    private void audit(
-            final String event,
-            final Result result,
-            final Object before,
-            final Object output,
-            final Object... input) {
-
-        notificationManager.createTasks(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
-                profile.getTask().getResource().getKey(),
-                event,
-                result,
-                before,
-                output,
-                input);
-
-        auditManager.audit(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
-                profile.getTask().getResource().getKey(),
-                event,
-                result,
-                before,
-                output,
-                input);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
deleted file mode 100644
index bf2cd6e..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-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.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
-import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncopeResultHandler;
-import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
-import org.apache.syncope.core.provisioning.api.AuditManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningActions;
-import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
-import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
-        implements SyncopeResultHandler<T, A> {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
-
-    @Autowired
-    protected AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    /**
-     * ConnectorObject utils.
-     */
-    @Autowired
-    protected ConnObjectUtils connObjectUtils;
-
-    /**
-     * Notification Manager.
-     */
-    @Autowired
-    protected NotificationManager notificationManager;
-
-    /**
-     * Audit Manager.
-     */
-    @Autowired
-    protected AuditManager auditManager;
-
-    /**
-     * Propagation manager.
-     */
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    /**
-     * Task executor.
-     */
-    @Autowired
-    protected PropagationTaskExecutor taskExecutor;
-
-    protected AnyObjectWorkflowAdapter awfAdapter;
-
-    /**
-     * User workflow adapter.
-     */
-    @Autowired
-    protected UserWorkflowAdapter uwfAdapter;
-
-    /**
-     * Group workflow adapter.
-     */
-    @Autowired
-    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 AnyUtilsFactory anyUtilsFactory;
-
-    /**
-     * Sync profile.
-     */
-    protected ProvisioningProfile<T, A> profile;
-
-    protected abstract AnyUtils getAnyUtils();
-
-    protected abstract AnyTO getAnyTO(long key);
-
-    protected abstract Any<?> getAny(long key);
-
-    protected abstract AnyPatch newPatch(final long key);
-
-    protected abstract WorkflowResult<Long> update(AnyPatch patch);
-
-    @Override
-    public void setProfile(final ProvisioningProfile<T, A> profile) {
-        this.profile = profile;
-    }
-
-    @Override
-    public ProvisioningProfile<T, A> getProfile() {
-        return profile;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
deleted file mode 100644
index 6f83727..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectPushResultHandler;
-
-public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
-    }
-
-    @Override
-    protected String getName(final Any<?> any) {
-        return StringUtils.EMPTY;
-    }
-
-    @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 AnyTO getAnyTO(final long key) {
-        return anyObjectDataBinder.getAnyObjectTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        AnyObjectPatch patch = new AnyObjectPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        return awfAdapter.update((AnyObjectPatch) patch);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
deleted file mode 100644
index a8c6c1b..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-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.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.syncpull.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 ProvisioningManager<?, ?> getProvisioningManager() {
-        return anyObjectProvisioningManager;
-    }
-
-    @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 AnyTO getAnyTO(final long key) {
-        return anyObjectDataBinder.getAnyObjectTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        AnyObjectPatch patch = new AnyObjectPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        return awfAdapter.update((AnyObjectPatch) patch);
-    }
-
-    @Override
-    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
-        AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
-
-        Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
-                anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
-        result.setKey(created.getKey());
-        result.setName(getName(anyTO));
-
-        return getAnyTO(created.getKey());
-    }
-
-    @Override
-    protected AnyTO doUpdate(
-            final AnyTO before,
-            final AnyPatch anyPatch,
-            final SyncDelta delta,
-            final ProvisioningReport result) {
-
-        AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
-
-        Map.Entry<Long, List<PropagationStatus>> updated =
-                anyObjectProvisioningManager.update(anyObjectPatch, true);
-
-        AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
-        result.setName(getName(after));
-        return after;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
deleted file mode 100644
index 84504ec..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-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;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * A SyncActions implementation which allows the ability to import passwords from a Database
- * backend, where the passwords are hashed according to the password cipher algorithm property
- * of the (DB) Connector and HEX-encoded.
- */
-public class DBPasswordSyncActions extends DefaultSyncActions {
-
-    private static final Logger LOG = LoggerFactory.getLogger(DBPasswordSyncActions.class);
-
-    private static final String CLEARTEXT = "CLEARTEXT";
-
-    @Autowired
-    private UserDAO userDAO;
-
-    private String encodedPassword;
-
-    private CipherAlgorithm cipher;
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any) throws JobExecutionException {
-
-        if (any instanceof UserTO) {
-            String password = ((UserTO) any).getPassword();
-            parseEncodedPassword(password, profile.getConnector());
-        }
-
-        return delta;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final M anyPatch) throws JobExecutionException {
-
-        if (anyPatch instanceof UserPatch) {
-            PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
-            parseEncodedPassword(modPassword == null ? null : modPassword.getValue(), profile.getConnector());
-        }
-
-        return delta;
-    }
-
-    private void parseEncodedPassword(final String password, final Connector connector) {
-        if (password != null) {
-            ConnInstance connInstance = connector.getConnInstance();
-
-            String cipherAlgorithm = getCipherAlgorithm(connInstance);
-            if (!CLEARTEXT.equals(cipherAlgorithm)) {
-                try {
-                    encodedPassword = password;
-                    cipher = CipherAlgorithm.valueOf(cipherAlgorithm);
-                } catch (IllegalArgumentException e) {
-                    LOG.error("Cipher algorithm not allowed: {}", cipherAlgorithm, e);
-                    encodedPassword = null;
-                }
-            }
-        }
-    }
-
-    private String getCipherAlgorithm(final ConnInstance connInstance) {
-        ConnConfProperty cipherAlgorithm =
-                IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
-
-                    @Override
-                    public boolean evaluate(final ConnConfProperty property) {
-                        return "cipherAlgorithm".equals(property.getSchema().getName())
-                        && property.getValues() != null && !property.getValues().isEmpty();
-                    }
-                });
-
-        return cipherAlgorithm == null
-                ? CLEARTEXT
-                : (String) cipherAlgorithm.getValues().get(0);
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO> void after(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final ProvisioningReport result) throws JobExecutionException {
-
-        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
-            User syncopeUser = userDAO.find(any.getKey());
-            if (syncopeUser != null) {
-                syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
-            }
-            encodedPassword = null;
-            cipher = null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
deleted file mode 100644
index 49135f9..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.quartz.JobExecutionException;
-
-/**
- * Default (empty) implementation of PushActions.
- */
-public abstract class DefaultPushActions implements PushActions {
-
-    @Override
-    public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any)
-            throws JobExecutionException {
-
-        return any;
-    }
-
-    @Override
-    public <A extends Any<?>> void onError(
-            final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result,
-            final Exception error) throws JobExecutionException {
-
-        // do nothing
-    }
-
-    @Override
-    public <A extends Any<?>> void after(
-            final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result)
-            throws JobExecutionException {
-
-        // do nothing
-    }
-
-    @Override
-    public void afterAll(final ProvisioningProfile<?, ?> profile)
-            throws JobExecutionException {
-
-        // do nothing
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
deleted file mode 100644
index f82b40c..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import static org.identityconnectors.framework.impl.api.local.operations.FilteredResultsHandler.PassThroughFilter;
-
-import org.identityconnectors.framework.common.objects.filter.Filter;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
-
-/**
- * Default (pass-through) implementation of {@link ReconciliationFilterBuilder}.
- */
-public abstract class DefaultReconciliationFilterBuilder implements ReconciliationFilterBuilder {
-
-    private static final PassThroughFilter PASS_THROUGH = new PassThroughFilter();
-
-    @Override
-    public Filter build() {
-        return PASS_THROUGH;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
deleted file mode 100644
index 159382c..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-/**
- * Default (empty) implementation of {@link SyncActions}.
- */
-public abstract class DefaultSyncActions implements SyncActions {
-
-    @Override
-    public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
-    }
-
-    @Override
-    public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final P anyMod) throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeDelete(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeAssign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeLink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeUnassign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeDeprovision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public <A extends AnyTO> SyncDelta beforeUnlink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
-            throws JobExecutionException {
-
-        return delta;
-    }
-
-    @Override
-    public void onError(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final ProvisioningReport result,
-            final Exception error) throws JobExecutionException {
-    }
-
-    @Override
-    public <A extends AnyTO> void after(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any,
-            final ProvisioningReport result)
-            throws JobExecutionException {
-    }
-
-    @Override
-    public void afterAll(final ProvisioningProfile<?, ?> profile)
-            throws JobExecutionException {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
deleted file mode 100644
index 0455b08..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-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.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.GroupPushResultHandler;
-
-public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
-    }
-
-    @Override
-    protected String getName(final Any<?> any) {
-        return Group.class.cast(any).getName();
-    }
-
-    @Override
-    protected Any<?> getAny(final long key) {
-        try {
-            return groupDAO.authFind(key);
-        } catch (Exception e) {
-            LOG.warn("Error retrieving group {}", key, e);
-            return null;
-        }
-    }
-
-    @Override
-    protected AnyTO getAnyTO(final long key) {
-        return groupDataBinder.getGroupTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        GroupPatch patch = new GroupPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        return gwfAdapter.update((GroupPatch) patch);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
deleted file mode 100644
index 8b73e42..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-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.AnyTypeKind;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.syncpull.GroupSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implements GroupSyncResultHandler {
-
-    protected final Map<Long, String> groupOwnerMap = new HashMap<>();
-
-    @Override
-    public Map<Long, String> getGroupOwnerMap() {
-        return this.groupOwnerMap;
-    }
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
-    }
-
-    @Override
-    protected String getName(final AnyTO anyTO) {
-        return GroupTO.class.cast(anyTO).getName();
-    }
-
-    @Override
-    protected ProvisioningManager<?, ?> getProvisioningManager() {
-        return groupProvisioningManager;
-    }
-
-    @Override
-    protected Any<?> getAny(final long key) {
-        try {
-            return groupDAO.authFind(key);
-        } catch (Exception e) {
-            LOG.warn("Error retrieving group {}", key, e);
-            return null;
-        }
-    }
-
-    @Override
-    protected AnyTO getAnyTO(final long key) {
-        return groupDataBinder.getGroupTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        GroupPatch patch = new GroupPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        return gwfAdapter.update((GroupPatch) patch);
-    }
-
-    @Override
-    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
-        GroupTO groupTO = GroupTO.class.cast(anyTO);
-
-        Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(
-                groupTO,
-                groupOwnerMap,
-                Collections.singleton(profile.getTask().getResource().getKey()),
-                true);
-
-        result.setKey(created.getKey());
-        result.setName(getName(anyTO));
-
-        return getAnyTO(created.getKey());
-    }
-
-    @Override
-    protected AnyTO doUpdate(
-            final AnyTO before,
-            final AnyPatch anyPatch,
-            final SyncDelta delta,
-            final ProvisioningReport result) {
-
-        GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
-
-        Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupPatch, true);
-
-        String groupOwner = null;
-        for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
-            if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
-                    && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
-
-                groupOwner = attrPatch.getAttrTO().getValues().get(0);
-            }
-        }
-        if (groupOwner != null) {
-            groupOwnerMap.put(updated.getKey(), groupOwner);
-        }
-
-        GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
-
-        result.setName(getName(after));
-
-        return after;
-    }
-
-}


[06/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
new file mode 100644
index 0000000..ed1a702
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -0,0 +1,248 @@
+/*
+ * 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.pushpull;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+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.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
+
+public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    protected PullUtils pullUtils;
+
+    protected void setGroupOwners(final GroupPullResultHandler ghandler) {
+        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
+            Group group = groupDAO.find(entry.getKey());
+            if (group == null) {
+                throw new NotFoundException("Group " + entry.getKey());
+            }
+
+            if (StringUtils.isBlank(entry.getValue())) {
+                group.setGroupOwner(null);
+                group.setUserOwner(null);
+            } else {
+                Long userKey = pullUtils.findMatchingAnyKey(
+                        anyTypeDAO.findUser(),
+                        entry.getValue(),
+                        ghandler.getProfile().getTask().getResource(),
+                        ghandler.getProfile().getConnector());
+
+                if (userKey == null) {
+                    Long groupKey = pullUtils.findMatchingAnyKey(
+                            anyTypeDAO.findGroup(),
+                            entry.getValue(),
+                            ghandler.getProfile().getTask().getResource(),
+                            ghandler.getProfile().getConnector());
+
+                    if (groupKey != null) {
+                        group.setGroupOwner(groupDAO.find(groupKey));
+                    }
+                } else {
+                    group.setUserOwner(userDAO.find(userKey));
+                }
+            }
+
+            groupDAO.save(group);
+        }
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final PullTask pullTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing pull on {}", pullTask.getResource());
+
+        List<PullActions> actions = new ArrayList<>();
+        for (String className : pullTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+                PullActions pullActions = (PullActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+
+                actions.add(pullActions);
+            } catch (Exception e) {
+                LOG.warn("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<PullTask, PullActions> profile = new ProvisioningProfile<>(connector, pullTask);
+        profile.getActions().addAll(actions);
+        profile.setDryRun(dryRun);
+        profile.setResAct(getPullPolicySpec(pullTask).getConflictResolutionAction());
+
+        // Prepare handler for SyncDelta objects (any objects)
+        AnyObjectPullResultHandler ahandler = (AnyObjectPullResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (users)
+        UserPullResultHandler uhandler = (UserPullResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (groups)
+        GroupPullResultHandler ghandler = (GroupPullResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (PullActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : pullTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                SyncResultsHandler handler;
+                switch (provision.getAnyType().getKind()) {
+                    case USER:
+                        handler = uhandler;
+                        break;
+
+                    case GROUP:
+                        handler = ghandler;
+                        break;
+
+                    case ANY_OBJECT:
+                    default:
+                        handler = ahandler;
+                }
+
+                try {
+                    Set<MappingItem> linkinMappingItems = new HashSet<>();
+                    for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
+                        linkinMappingItems.add(virSchema.asLinkingMappingItem());
+                    }
+                    Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
+                            provision.getMapping().getItems().iterator(),
+                            linkinMappingItems.iterator());
+
+                    switch (pullTask.getPullMode()) {
+                        case INCREMENTAL:
+                            SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                            connector.sync(provision.getObjectClass(),
+                                    provision.getSyncToken(),
+                                    handler,
+                                    MappingManagerImpl.buildOperationOptions(mapItems));
+                            if (!dryRun) {
+                                provision.setSyncToken(latestSyncToken);
+                                resourceDAO.save(provision.getResource());
+                            }
+                            break;
+
+                        case FILTERED_RECONCILIATION:
+                            ReconciliationFilterBuilder filterBuilder =
+                                    (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
+                                    createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
+                                            AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+                            connector.filteredReconciliation(provision.getObjectClass(),
+                                    filterBuilder,
+                                    handler,
+                                    MappingManagerImpl.buildOperationOptions(mapItems));
+                            break;
+
+                        case FULL_RECONCILIATION:
+                        default:
+                            connector.fullReconciliation(provision.getObjectClass(),
+                                    handler,
+                                    MappingManagerImpl.buildOperationOptions(mapItems));
+                            break;
+                    }
+                } catch (Throwable t) {
+                    throw new JobExecutionException("While pulling from connector", t);
+                }
+            }
+        }
+
+        try {
+            setGroupOwners(ghandler);
+        } catch (Exception e) {
+            LOG.error("While setting group owners", e);
+        }
+
+        if (!profile.isDryRun()) {
+            for (PullActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), pullTask.getResource().getPullTraceLevel(), dryRun);
+
+        LOG.debug("Pull result: {}", result);
+
+        return result;
+    }
+
+    private PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
+        PullPolicySpec pullPolicySpec;
+
+        if (task instanceof PullTask) {
+            pullPolicySpec = task.getResource().getPullPolicy() == null
+                    ? null
+                    : task.getResource().getPullPolicy().getSpecification();
+        } else {
+            pullPolicySpec = null;
+        }
+
+        // step required because the call <policy>.getSpecification() could return a null value
+        return pullPolicySpec == null ? new PullPolicySpec() : pullPolicySpec;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
new file mode 100644
index 0000000..a0f558c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
@@ -0,0 +1,317 @@
+/*
+ * 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.pushpull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+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.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.identityconnectors.framework.common.objects.ResultsHandler;
+import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+
+@Transactional(readOnly = true)
+@Component
+public class PullUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PullUtils.class);
+
+    /**
+     * Schema DAO.
+     */
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    /**
+     * Any Object DAO.
+     */
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    /**
+     * User DAO.
+     */
+    @Autowired
+    private UserDAO userDAO;
+
+    /**
+     * Group DAO.
+     */
+    @Autowired
+    private GroupDAO groupDAO;
+
+    /**
+     * Search DAO.
+     */
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
+    public Long findMatchingAnyKey(
+            final AnyType anyType,
+            final String name,
+            final ExternalResource resource,
+            final Connector connector) {
+
+        Provision provision = resource.getProvision(anyType);
+        if (provision == null) {
+            return null;
+        }
+
+        Long result = null;
+
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind());
+
+        final List<ConnectorObject> found = new ArrayList<>();
+        connector.search(provision.getObjectClass(),
+                new EqualsFilter(new Name(name)),
+                new ResultsHandler() {
+
+            @Override
+            public boolean handle(final ConnectorObject obj) {
+                return found.add(obj);
+            }
+        },
+                MappingManagerImpl.buildOperationOptions(MappingManagerImpl.getPullMappingItems(provision).iterator()));
+
+        if (found.isEmpty()) {
+            LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
+        } else {
+            if (found.size() > 1) {
+                LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
+                        provision.getObjectClass(), resource, name);
+            }
+
+            ConnectorObject connObj = found.iterator().next();
+            try {
+                List<Long> anyKeys = findExisting(connObj.getUid().getUidValue(), connObj, provision, anyUtils);
+                if (anyKeys.isEmpty()) {
+                    LOG.debug("No matching {} found for {}, aborting", anyUtils.getAnyTypeKind(), connObj);
+                } else {
+                    if (anyKeys.size() > 1) {
+                        LOG.warn("More than one {} found {} - taking first only", anyUtils.getAnyTypeKind(), anyKeys);
+                    }
+
+                    result = anyKeys.iterator().next();
+                }
+            } catch (IllegalArgumentException e) {
+                LOG.warn(e.getMessage());
+            }
+        }
+
+        return result;
+    }
+
+    private AnyDAO<?> getAnyDAO(final MappingItem connObjectKeyItem) {
+        return AnyTypeKind.USER == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
+                ? userDAO
+                : AnyTypeKind.ANY_OBJECT == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
+                        ? anyObjectDAO
+                        : groupDAO;
+    }
+
+    private List<Long> findByConnObjectKeyItem(
+            final String uid, final Provision provision, final AnyUtils anyUtils) {
+
+        List<Long> result = new ArrayList<>();
+
+        MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
+
+        String transfUid = uid;
+        for (MappingItemTransformer transformer : MappingManagerImpl.getMappingItemTransformers(connObjectKeyItem)) {
+            List<Object> output = transformer.beforePull(Collections.<Object>singletonList(transfUid));
+            if (output != null && !output.isEmpty()) {
+                transfUid = output.get(0).toString();
+            }
+        }
+
+        switch (connObjectKeyItem.getIntMappingType()) {
+            case UserPlainSchema:
+            case GroupPlainSchema:
+            case AnyObjectPlainSchema:
+                PlainAttrValue value = anyUtils.newPlainAttrValue();
+
+                PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
+                if (schema == null) {
+                    value.setStringValue(transfUid);
+                } else {
+                    try {
+                        value.parseValue(schema, transfUid);
+                    } catch (ParsingValidationException e) {
+                        LOG.error("While parsing provided __UID__ {}", transfUid, e);
+                        value.setStringValue(transfUid);
+                    }
+                }
+
+                List<? extends Any<?>> anys =
+                        getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value);
+                for (Any<?> any : anys) {
+                    result.add(any.getKey());
+                }
+                break;
+
+            case UserDerivedSchema:
+            case GroupDerivedSchema:
+            case AnyObjectDerivedSchema:
+                anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), transfUid);
+                for (Any<?> any : anys) {
+                    result.add(any.getKey());
+                }
+                break;
+
+            case UserKey:
+            case GroupKey:
+            case AnyObjectKey:
+                Any<?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid));
+                if (any != null) {
+                    result.add(any.getKey());
+                }
+                break;
+
+            case Username:
+                User user = userDAO.find(transfUid);
+                if (user != null) {
+                    result.add(user.getKey());
+                }
+                break;
+
+            case GroupName:
+                Group group = groupDAO.find(transfUid);
+                if (group != null) {
+                    result.add(group.getKey());
+                }
+                break;
+
+            default:
+                LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
+        }
+
+        return result;
+    }
+
+    private List<Long> findByCorrelationRule(
+            final ConnectorObject connObj, final PullCorrelationRule rule, final AnyTypeKind type) {
+
+        List<Long> result = new ArrayList<>();
+        for (Any<?> any : searchDAO.search(rule.getSearchCond(connObj), type)) {
+            result.add(any.getKey());
+        }
+
+        return result;
+    }
+
+    private PullCorrelationRule getCorrelationRule(final Provision provision, final PullPolicySpec policySpec) {
+        PullCorrelationRule result = null;
+
+        String pullCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
+        if (StringUtils.isNotBlank(pullCorrelationRule)) {
+            if (pullCorrelationRule.charAt(0) == '[') {
+                result = new PlainAttrsPullCorrelationRule(
+                        POJOHelper.deserialize(pullCorrelationRule, String[].class), provision);
+            } else {
+                try {
+                    result = (PullCorrelationRule) Class.forName(pullCorrelationRule).newInstance();
+                } catch (Exception e) {
+                    LOG.error("Failure instantiating correlation rule class '{}'", pullCorrelationRule, e);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Find any objects based on mapped uid value (or previous uid value, if updated).
+     *
+     * @param uid for finding by connObjectKey
+     * @param connObj for finding by attribute value
+     * @param provision external resource
+     * @param anyUtils any util
+     * @return list of matching users / groups
+     */
+    public List<Long> findExisting(
+            final String uid,
+            final ConnectorObject connObj,
+            final Provision provision,
+            final AnyUtils anyUtils) {
+
+        PullPolicySpec pullPolicySpec = null;
+        if (provision.getResource().getPullPolicy() != null) {
+            pullPolicySpec = provision.getResource().getPullPolicy().getSpecification();
+        }
+
+        PullCorrelationRule pullRule = null;
+        if (pullPolicySpec != null) {
+            pullRule = getCorrelationRule(provision, pullPolicySpec);
+        }
+
+        return pullRule == null
+                ? findByConnObjectKeyItem(uid, provision, anyUtils)
+                : findByCorrelationRule(connObj, pullRule, anyUtils.getAnyTypeKind());
+    }
+
+    public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
+        Boolean enabled = null;
+        if (task.isPullStatus()) {
+            Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes());
+            if (status != null && status.getValue() != null && !status.getValue().isEmpty()) {
+                enabled = (Boolean) status.getValue().get(0);
+            }
+        }
+
+        return enabled;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
new file mode 100644
index 0000000..563c64a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.pushpull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
+
+    private static final int PAGE_SIZE = 1000;
+
+    /**
+     * User DAO.
+     */
+    @Autowired
+    private UserDAO userDAO;
+
+    /**
+     * Search DAO.
+     */
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    /**
+     * Group DAO.
+     */
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+        AnyDAO<?> result;
+        switch (anyTypeKind) {
+            case USER:
+                result = userDAO;
+                break;
+
+            case GROUP:
+                result = groupDAO;
+                break;
+
+            case ANY_OBJECT:
+            default:
+                result = anyObjectDAO;
+        }
+
+        return result;
+    }
+
+    protected void handle(
+            final List<? extends Any<?>> anys,
+            final SyncopePushResultHandler handler,
+            final ExternalResource resource)
+            throws JobExecutionException {
+
+        for (Any<?> any : anys) {
+            try {
+                handler.handle(any.getKey());
+            } catch (Exception e) {
+                LOG.warn("Failure pushing '{}' on '{}'", any, resource, e);
+                throw new JobExecutionException("While pushing " + any + " on " + resource, e);
+            }
+        }
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final PushTask pushTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing push on {}", pushTask.getResource());
+
+        List<PushActions> actions = new ArrayList<>();
+        for (String className : pushTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+
+                PushActions pushActions = (PushActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+                actions.add(pushActions);
+            } catch (Exception e) {
+                LOG.info("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+        profile.setDryRun(dryRun);
+        profile.setResAct(null);
+
+        AnyObjectPushResultHandler ahandler =
+                (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        UserPushResultHandler uhandler =
+                (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        GroupPushResultHandler ghandler =
+                (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : pushTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
+
+                SyncopePushResultHandler handler;
+                switch (provision.getAnyType().getKind()) {
+                    case USER:
+                        handler = uhandler;
+                        break;
+
+                    case GROUP:
+                        handler = ghandler;
+                        break;
+
+                    case ANY_OBJECT:
+                    default:
+                        handler = ahandler;
+                }
+
+                String filter = pushTask.getFilter(provision.getAnyType()) == null
+                        ? null
+                        : pushTask.getFilter(provision.getAnyType()).getFIQLCond();
+                if (StringUtils.isBlank(filter)) {
+                    handle(anyDAO.findAll(), handler, pushTask.getResource());
+                } else {
+                    int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+                    for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+                        List<? extends Any<?>> anys = searchDAO.search(
+                                SyncopeConstants.FULL_ADMIN_REALMS,
+                                SearchCondConverter.convert(filter),
+                                page,
+                                PAGE_SIZE,
+                                Collections.<OrderByClause>emptyList(),
+                                provision.getAnyType().getKind());
+                        handle(anys, handler, pushTask.getResource());
+                    }
+                }
+            }
+        }
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), pushTask.getResource().getPullTraceLevel(), dryRun);
+        LOG.debug("Sync result: {}", result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
new file mode 100644
index 0000000..ddc01fb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPullResultHandlerImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.pushpull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler;
+
+public class UserPullResultHandlerImpl extends AbstractPullResultHandler implements UserPullResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+    }
+
+    @Override
+    protected String getName(final AnyTO anyTO) {
+        return UserTO.class.cast(anyTO).getUsername();
+    }
+
+    @Override
+    protected ProvisioningManager<?, ?> getProvisioningManager() {
+        return userProvisioningManager;
+    }
+
+    @Override
+    protected Any<?> getAny(final long key) {
+        try {
+            return userDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving user {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        return userDataBinder.getUserTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        UserPatch patch = new UserPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+        return new WorkflowResult<>(
+                update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
+    }
+
+    @Override
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+        UserTO userTO = UserTO.class.cast(anyTO);
+
+        Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+        Map.Entry<Long, List<PropagationStatus>> created =
+                userProvisioningManager.create(userTO, true, true, enabled,
+                        Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+        result.setKey(created.getKey());
+        result.setName(getName(anyTO));
+
+        return getAnyTO(created.getKey());
+    }
+
+    @Override
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyPatch anyPatch,
+            final SyncDelta delta,
+            final ProvisioningReport result) {
+
+        UserPatch userPatch = UserPatch.class.cast(anyPatch);
+        Boolean enabled = pullUtils.readEnabled(delta.getObject(), profile.getTask());
+
+        Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(
+                userPatch,
+                result,
+                enabled,
+                Collections.singleton(profile.getTask().getResource().getKey()),
+                true);
+
+        return getAnyTO(updated.getKey());
+    }
+
+    @Override
+    protected void doDelete(final AnyTypeKind kind, final Long key) {
+        try {
+            userProvisioningManager.delete(
+                    key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
+        } catch (Exception e) {
+            // A propagation failure doesn't imply a pull failure.
+            // The propagation exception status will be reported into the propagation task execution.
+            LOG.error("Could not propagate user " + key, e);
+        }
+
+        uwfAdapter.delete(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
new file mode 100644
index 0000000..bc63845
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/UserPushResultHandlerImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.pushpull;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+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.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler;
+
+public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+    }
+
+    @Override
+    protected void provision(final Any<?> any, final Boolean enabled) {
+        AnyTO before = getAnyTO(any.getKey());
+
+        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.getUserCreateTasks(
+                before.getKey(),
+                null,
+                enabled,
+                propByRes,
+                before.getVirAttrs(),
+                noPropResources));
+    }
+
+    @Override
+    protected String getName(final Any<?> any) {
+        return User.class.cast(any).getUsername();
+    }
+
+    @Override
+    protected Any<?> getAny(final long key) {
+        try {
+            return userDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving user {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        return userDataBinder.getUserTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        UserPatch patch = new UserPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+        return new WorkflowResult<>(
+                update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
deleted file mode 100644
index 258e106..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-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.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
-import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.MappingManager;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncopePushResultHandler;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
-        implements SyncopePushResultHandler {
-
-    @Autowired
-    protected MappingManager mappingManager;
-
-    protected abstract String getName(Any<?> any);
-
-    protected void deprovision(final Any<?> any) {
-        AnyTO before = getAnyTO(any.getKey());
-
-        List<String> noPropResources = new ArrayList<>(before.getResources());
-        noPropResources.remove(profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getDeleteTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                null,
-                noPropResources));
-    }
-
-    protected void provision(final Any<?> any, final Boolean enabled) {
-        AnyTO before = getAnyTO(any.getKey());
-
-        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.getCreateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                propByRes,
-                before.getVirAttrs(),
-                noPropResources));
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void link(final Any<?> any, final Boolean unlink) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void unassign(final Any<?> any) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.DELETE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-
-        deprovision(any);
-    }
-
-    protected void assign(final Any<?> any, final Boolean enabled) {
-        AnyPatch patch = newPatch(any.getKey());
-        patch.getResources().add(new StringPatchItem.Builder().
-                operation(PatchOperation.ADD_REPLACE).
-                value(profile.getTask().getResource().getKey()).build());
-
-        update(patch);
-
-        provision(any, enabled);
-    }
-
-    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
-        ConnectorObject obj = null;
-        try {
-            Uid uid = new Uid(connObjectKey);
-
-            obj = profile.getConnector().getObject(objectClass,
-                    uid,
-                    MappingManagerImpl.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
-        } catch (TimeoutException toe) {
-            LOG.debug("Request timeout", toe);
-            throw toe;
-        } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", connObjectKey, ignore);
-        }
-
-        return obj;
-    }
-
-    @Transactional(propagation = Propagation.REQUIRES_NEW)
-    @Override
-    public boolean handle(final long anyKey) {
-        Any<?> any = null;
-        try {
-            any = getAny(anyKey);
-            doHandle(any);
-            return true;
-        } catch (IgnoreProvisionException e) {
-            ProvisioningReport result = new ProvisioningReport();
-            result.setOperation(ResourceOperation.NONE);
-            result.setAnyType(any == null ? null : any.getType().getKey());
-            result.setStatus(ProvisioningReport.Status.IGNORE);
-            result.setKey(anyKey);
-            profile.getResults().add(result);
-
-            LOG.warn("Ignoring during push", e);
-            return true;
-        } catch (JobExecutionException e) {
-            LOG.error("Push failed", e);
-            return false;
-        }
-    }
-
-    protected final void doHandle(final Any<?> any) throws JobExecutionException {
-        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
-        ProvisioningReport result = new ProvisioningReport();
-        profile.getResults().add(result);
-
-        result.setKey(any.getKey());
-        result.setAnyType(any.getType().getKey());
-        result.setName(getName(any));
-
-        Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
-                ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
-                : null;
-
-        LOG.debug("Propagating {} with key {} towards {}",
-                anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
-
-        Object output = null;
-        Result resultStatus = null;
-        String operation = null;
-
-        // Try to read remote object BEFORE any actual operation
-        Provision provision = profile.getTask().getResource().getProvision(any.getType());
-        String connObjecKey = mappingManager.getConnObjectKeyValue(any, provision);
-
-        ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
-
-        Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
-
-        if (profile.isDryRun()) {
-            if (beforeObj == null) {
-                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-            } else {
-                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-            }
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
-        } else {
-            try {
-                if (beforeObj == null) {
-                    operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
-                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-
-                    switch (profile.getTask().getUnmatchingRule()) {
-                        case ASSIGN:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeAssign(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformCreate()) {
-                                LOG.debug("PushTask not configured for create");
-                            } else {
-                                assign(any, status);
-                            }
-
-                            break;
-
-                        case PROVISION:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeProvision(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformCreate()) {
-                                LOG.debug("PushTask not configured for create");
-                            } else {
-                                provision(any, status);
-                            }
-
-                            break;
-
-                        case UNLINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, true);
-                            }
-
-                            break;
-
-                        case IGNORE:
-                            LOG.debug("Ignored any: {}", any);
-                            break;
-                        default:
-                        // do nothing
-                    }
-                } else {
-                    operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
-                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-
-                    switch (profile.getTask().getMatchingRule()) {
-                        case UPDATE:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUpdate(this.getProfile(), any);
-                            }
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                update(any, status);
-                            }
-
-                            break;
-
-                        case DEPROVISION:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformDelete()) {
-                                LOG.debug("PushTask not configured for delete");
-                            } else {
-                                deprovision(any);
-                            }
-
-                            break;
-
-                        case UNASSIGN:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformDelete()) {
-                                LOG.debug("PushTask not configured for delete");
-                            } else {
-                                unassign(any);
-                            }
-
-                            break;
-
-                        case LINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, false);
-                            }
-
-                            break;
-
-                        case UNLINK:
-                            for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), any);
-                            }
-
-                            if (!profile.getTask().isPerformUpdate()) {
-                                LOG.debug("PushTask not configured for update");
-                            } else {
-                                link(any, true);
-                            }
-
-                            break;
-
-                        case IGNORE:
-                            LOG.debug("Ignored any: {}", any);
-                            break;
-                        default:
-                        // do nothing
-                    }
-                }
-
-                for (PushActions action : profile.getActions()) {
-                    action.after(this.getProfile(), any, result);
-                }
-
-                result.setStatus(ProvisioningReport.Status.SUCCESS);
-                resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(connObjecKey, provision.getObjectClass());
-            } catch (IgnoreProvisionException e) {
-                throw e;
-            } catch (Exception e) {
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                resultStatus = AuditElements.Result.FAILURE;
-                output = e;
-
-                LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
-
-                for (PushActions action : profile.getActions()) {
-                    action.onError(this.getProfile(), any, result, e);
-                }
-
-                throw new JobExecutionException(e);
-            } finally {
-                notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
-                        any.getType().getKind().name().toLowerCase(),
-                        profile.getTask().getResource().getKey(),
-                        operation,
-                        resultStatus,
-                        beforeObj,
-                        output,
-                        any);
-                auditManager.audit(AuditElements.EventCategoryType.PUSH,
-                        any.getType().getKind().name().toLowerCase(),
-                        profile.getTask().getResource().getKey(),
-                        operation,
-                        resultStatus,
-                        connObjectUtils.getConnObjectTO(beforeObj),
-                        output instanceof ConnectorObject
-                                ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
-                        any);
-            }
-        }
-    }
-
-    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
-        switch (rule) {
-            case ASSIGN:
-            case PROVISION:
-                return ResourceOperation.CREATE;
-            default:
-                return ResourceOperation.NONE;
-        }
-    }
-
-    private ResourceOperation getResourceOperation(final MatchingRule rule) {
-        switch (rule) {
-            case UPDATE:
-                return ResourceOperation.UPDATE;
-            case DEPROVISION:
-            case UNASSIGN:
-                return ResourceOperation.DELETE;
-            default:
-                return ResourceOperation.NONE;
-        }
-    }
-
-    protected Any<?> update(final Any<?> any, final Boolean enabled) {
-        boolean changepwd;
-        Collection<String> resourceNames;
-        if (any instanceof User) {
-            changepwd = true;
-            resourceNames = userDAO.findAllResourceNames((User) any);
-        } else if (any instanceof AnyObject) {
-            changepwd = false;
-            resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
-        } else {
-            changepwd = false;
-            resourceNames = ((Group) any).getResourceNames();
-        }
-
-        List<String> noPropResources = new ArrayList<>(resourceNames);
-        noPropResources.remove(profile.getTask().getResource().getKey());
-
-        PropagationByResource propByRes = new PropagationByResource();
-        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
-        taskExecutor.execute(propagationManager.getUpdateTasks(
-                any.getType().getKind(),
-                any.getKey(),
-                changepwd,
-                null,
-                propByRes,
-                null,
-                noPropResources));
-
-        return getAny(any.getKey());
-    }
-}


[13/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
[SYNCOPE-771] Rename completed


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

Branch: refs/heads/master
Commit: 61a7fdd38e412a30eeb24161400c669a2c3f3228
Parents: 40288e9
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Mar 11 14:45:35 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Mar 11 14:45:35 2016 +0100

----------------------------------------------------------------------
 .../syncope/client/cli/commands/info/Info.java  |   8 +-
 .../client/cli/commands/info/InfoCommand.java   |   4 +-
 .../cli/commands/info/InfoResultManager.java    |   2 +-
 .../cli/commands/policy/PolicyDetails.java      |   6 +-
 .../commands/policy/PolicyResultManager.java    |  12 +-
 .../resource/ResourceResultManager.java         |   4 +-
 .../client/cli/commands/task/TaskDetails.java   |  38 +-
 .../client/cli/commands/task/TaskList.java      |   2 +-
 .../cli/commands/task/TaskResultManager.java    |  58 +-
 .../cli/src/main/resources/messages.properties  |   4 +-
 .../client/console/commons/Constants.java       |   2 +-
 .../console/panels/ResourceMappingPanel.java    |   6 +-
 .../console/panels/ResourceSecurityPanel.java   |  28 +-
 .../client/console/rest/PolicyRestClient.java   |   2 +-
 .../client/console/rest/TaskRestClient.java     |  10 +-
 .../ProvisioningTaskSearchResultPanel.java      |   4 +-
 .../tasks/PullTaskSearchResultPanel.java        |  49 ++
 .../syncope/client/console/tasks/PullTasks.java |  53 ++
 .../console/tasks/SchedTaskWizardBuilder.java   |  36 +-
 .../tasks/SyncTaskSearchResultPanel.java        |  52 --
 .../syncope/client/console/tasks/SyncTasks.java |  53 --
 .../console/topology/TopologyTogglePanel.java   |  12 +-
 .../markup/html/form/MappingPurposePanel.java   |  24 +-
 .../console/panels/ResourceModal.properties     |   2 +-
 .../console/panels/ResourceModal_it.properties  |   2 +-
 .../panels/ResourceModal_pt_BR.properties       |   2 +-
 .../console/panels/ResourceSecurityPanel.html   |   2 +-
 .../panels/ResourceSecurityPanel.properties     |   2 +-
 .../panels/ResourceSecurityPanel_it.properties  |   2 +-
 .../ResourceSecurityPanel_pt_BR.properties      |   2 +-
 .../tasks/SchedTaskWizardBuilder$Profile.html   |   6 +-
 .../SchedTaskWizardBuilder$Profile.properties   |   8 +-
 ...SchedTaskWizardBuilder$Profile_it.properties |   8 +-
 ...edTaskWizardBuilder$Profile_pt_BR.properties |  10 +-
 .../console/topology/TopologyTogglePanel.html   |   2 +-
 .../topology/TopologyTogglePanel.properties     |   2 +-
 .../topology/TopologyTogglePanel_it.properties  |   2 +-
 .../TopologyTogglePanel_pt_BR.properties        |   2 +-
 .../markup/html/form/MappingPurposePanel.html   |   2 +-
 .../console/widgets/CompletenessWidget.html     |   2 +-
 .../widgets/CompletenessWidget.properties       |   2 +-
 .../widgets/CompletenessWidget_it.properties    |   2 +-
 .../widgets/CompletenessWidget_pt_BR.properties |   2 +-
 .../syncope/common/lib/info/PlatformInfo.java   |  24 +-
 .../common/lib/policy/AbstractPolicyTO.java     |   2 +-
 .../syncope/common/lib/policy/PolicyType.java   |   4 +-
 .../common/lib/policy/PullPolicySpec.java       |  64 ++
 .../syncope/common/lib/policy/PullPolicyTO.java |  45 +
 .../common/lib/policy/SyncPolicySpec.java       |  64 --
 .../syncope/common/lib/policy/SyncPolicyTO.java |  45 -
 .../lib/to/AbstractProvisioningTaskTO.java      |   6 +-
 .../syncope/common/lib/to/PullTaskTO.java       |  78 ++
 .../syncope/common/lib/to/ResourceTO.java       |  20 +-
 .../syncope/common/lib/to/SyncTaskTO.java       |  78 --
 .../syncope/common/lib/types/AuditElements.java |   2 +-
 .../common/lib/types/AuditLoggerName.java       |   4 +-
 .../common/lib/types/ClientExceptionType.java   |   2 +-
 .../common/lib/types/EntityViolationType.java   |   2 +-
 .../common/lib/types/MappingPurpose.java        |   2 +-
 .../syncope/common/lib/types/PullMode.java      |  29 +
 .../syncope/common/lib/types/SyncMode.java      |  29 -
 .../syncope/common/lib/types/TaskType.java      |   2 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |  10 +-
 .../apache/syncope/core/logic/PolicyLogic.java  |  10 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |   6 +-
 .../apache/syncope/core/logic/TaskLogic.java    |   4 +-
 .../init/ClassPathScanImplementationLookup.java |  24 +-
 .../syncope/core/logic/init/JobManagerImpl.java |  12 +-
 .../persistence/api/ImplementationLookup.java   |   2 +-
 .../api/entity/LinkingMappingItem.java          |   2 +-
 .../api/entity/policy/PullPolicy.java           |  30 +
 .../api/entity/policy/SyncPolicy.java           |  30 -
 .../api/entity/resource/ExternalResource.java   |  10 +-
 .../api/entity/task/AnyTemplatePullTask.java    |  28 +
 .../api/entity/task/AnyTemplateSyncTask.java    |  28 -
 .../api/entity/task/ProvisioningTask.java       |   4 +-
 .../persistence/api/entity/task/PullTask.java   |  45 +
 .../persistence/api/entity/task/SyncTask.java   |  45 -
 .../jpa/dao/JPAExternalResourceDAO.java         |   6 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java   |   2 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   8 +-
 .../jpa/entity/JPAEntityFactory.java            |  24 +-
 .../jpa/entity/policy/JPAPullPolicy.java        |  54 ++
 .../jpa/entity/policy/JPASyncPolicy.java        |  54 --
 .../entity/resource/JPAExternalResource.java    |  30 +-
 .../entity/task/AbstractProvisioningTask.java   |  14 +-
 .../jpa/entity/task/JPAAnyTemplatePullTask.java |  61 ++
 .../jpa/entity/task/JPAAnyTemplateSyncTask.java |  61 --
 .../jpa/entity/task/JPAPullTask.java            | 139 +++
 .../jpa/entity/task/JPAPushTaskAnyFilter.java   |   6 +-
 .../jpa/entity/task/JPASyncTask.java            | 139 ---
 .../jpa/entity/task/JPATaskUtils.java           |  16 +-
 .../jpa/entity/task/JPATaskUtilsFactory.java    |  12 +-
 .../entity/ProvisioningTaskCheck.java           |   2 +-
 .../entity/ProvisioningTaskValidator.java       |  26 +-
 .../resources/META-INF/spring-orm-oracle.xml    |   6 +-
 .../resources/META-INF/spring-orm-sqlserver.xml |   6 +-
 .../src/main/resources/META-INF/spring-orm.xml  |   6 +-
 .../core/persistence/jpa/inner/PolicyTest.java  |  32 +-
 .../core/persistence/jpa/inner/TaskTest.java    |   2 +-
 .../persistence/jpa/outer/PlainSchemaTest.java  |   4 +-
 .../persistence/jpa/outer/ResourceTest.java     |   2 +-
 .../core/persistence/jpa/outer/TaskTest.java    |  38 +-
 .../test/resources/domains/MasterContent.xml    | 154 ++--
 .../core/provisioning/api/Connector.java        |   2 +-
 .../api/UserProvisioningManager.java            |   2 +-
 .../api/data/MappingItemTransformer.java        |   6 +-
 .../pushpull/AnyObjectPullResultHandler.java    |  23 +
 .../pushpull/AnyObjectPushResultHandler.java    |  23 +
 .../api/pushpull/GroupPullResultHandler.java    |  26 +
 .../api/pushpull/GroupPushResultHandler.java    |  23 +
 .../api/pushpull/IgnoreProvisionException.java  |  29 +
 .../api/pushpull/ProvisioningActions.java       |  40 +
 .../api/pushpull/ProvisioningProfile.java       |  81 ++
 .../api/pushpull/ProvisioningReport.java        | 140 +++
 .../provisioning/api/pushpull/PullActions.java  | 203 +++++
 .../api/pushpull/PullCorrelationRule.java       |  36 +
 .../provisioning/api/pushpull/PushActions.java  | 163 ++++
 .../pushpull/ReconciliationFilterBuilder.java   |  30 +
 .../api/pushpull/SyncopePullResultHandler.java  |  29 +
 .../api/pushpull/SyncopePushResultHandler.java  |  26 +
 .../api/pushpull/SyncopeResultHandler.java      |  29 +
 .../api/pushpull/UserPullResultHandler.java     |  23 +
 .../api/pushpull/UserPushResultHandler.java     |  23 +
 .../syncpull/AnyObjectPushResultHandler.java    |  23 -
 .../syncpull/AnyObjectSyncResultHandler.java    |  23 -
 .../api/syncpull/GroupPushResultHandler.java    |  23 -
 .../api/syncpull/GroupSyncResultHandler.java    |  26 -
 .../api/syncpull/IgnoreProvisionException.java  |  29 -
 .../api/syncpull/ProvisioningActions.java       |  40 -
 .../api/syncpull/ProvisioningProfile.java       |  81 --
 .../api/syncpull/ProvisioningReport.java        | 140 ---
 .../provisioning/api/syncpull/PushActions.java  | 163 ----
 .../syncpull/ReconciliationFilterBuilder.java   |  30 -
 .../provisioning/api/syncpull/SyncActions.java  | 203 -----
 .../api/syncpull/SyncCorrelationRule.java       |  36 -
 .../api/syncpull/SyncopePushResultHandler.java  |  26 -
 .../api/syncpull/SyncopeResultHandler.java      |  29 -
 .../api/syncpull/SyncopeSyncResultHandler.java  |  29 -
 .../api/syncpull/UserPushResultHandler.java     |  23 -
 .../api/syncpull/UserSyncResultHandler.java     |  23 -
 .../provisioning/java/ConnectorFacadeProxy.java |   2 +-
 .../java/DefaultUserProvisioningManager.java    |   6 +-
 .../provisioning/java/MappingManagerImpl.java   |  10 +-
 .../data/DefaultMappingItemTransformer.java     |   2 +-
 .../java/data/PolicyDataBinderImpl.java         |  20 +-
 .../java/data/RealmDataBinderImpl.java          |   2 +-
 .../java/data/ResourceDataBinderImpl.java       |  14 +-
 .../java/data/TaskDataBinderImpl.java           |  74 +-
 .../LDAPMembershipPropagationActions.java       |   2 +-
 .../AbstractProvisioningJobDelegate.java        | 434 ++++++++++
 .../pushpull/AbstractPullResultHandler.java     | 797 +++++++++++++++++
 .../pushpull/AbstractPushResultHandler.java     | 434 ++++++++++
 .../pushpull/AbstractSyncopeResultHandler.java  | 155 ++++
 .../AnyObjectPullResultHandlerImpl.java         | 112 +++
 .../AnyObjectPushResultHandlerImpl.java         |  70 ++
 .../java/pushpull/DBPasswordPullActions.java    | 142 +++
 .../java/pushpull/DefaultPullActions.java       | 121 +++
 .../java/pushpull/DefaultPushActions.java       | 100 +++
 .../DefaultReconciliationFilterBuilder.java     |  38 +
 .../pushpull/GroupPullResultHandlerImpl.java    | 138 +++
 .../pushpull/GroupPushResultHandlerImpl.java    |  70 ++
 .../pushpull/LDAPMembershipPullActions.java     | 333 ++++++++
 .../java/pushpull/LDAPPasswordPullActions.java  | 124 +++
 .../pushpull/PlainAttrsPullCorrelationRule.java | 115 +++
 .../java/pushpull/PullJobDelegate.java          | 248 ++++++
 .../provisioning/java/pushpull/PullUtils.java   | 317 +++++++
 .../java/pushpull/PushJobDelegate.java          | 206 +++++
 .../pushpull/UserPullResultHandlerImpl.java     | 133 +++
 .../pushpull/UserPushResultHandlerImpl.java     |  96 +++
 .../AbstractProvisioningJobDelegate.java        | 434 ----------
 .../syncpull/AbstractPushResultHandler.java     | 434 ----------
 .../syncpull/AbstractSyncResultHandler.java     | 797 -----------------
 .../syncpull/AbstractSyncopeResultHandler.java  | 155 ----
 .../AnyObjectPushResultHandlerImpl.java         |  70 --
 .../AnyObjectSyncResultHandlerImpl.java         | 112 ---
 .../java/syncpull/DBPasswordSyncActions.java    | 142 ---
 .../java/syncpull/DefaultPushActions.java       | 100 ---
 .../DefaultReconciliationFilterBuilder.java     |  38 -
 .../java/syncpull/DefaultSyncActions.java       | 121 ---
 .../syncpull/GroupPushResultHandlerImpl.java    |  70 --
 .../syncpull/GroupSyncResultHandlerImpl.java    | 138 ---
 .../syncpull/LDAPMembershipSyncActions.java     | 335 --------
 .../java/syncpull/LDAPPasswordSyncActions.java  | 124 ---
 .../syncpull/PlainAttrsSyncCorrelationRule.java | 115 ---
 .../java/syncpull/PushJobDelegate.java          | 206 -----
 .../java/syncpull/SyncJobDelegate.java          | 248 ------
 .../provisioning/java/syncpull/SyncUtils.java   | 317 -------
 .../syncpull/UserPushResultHandlerImpl.java     |  96 ---
 .../syncpull/UserSyncResultHandlerImpl.java     | 133 ---
 .../java/utils/ConnObjectUtils.java             |  22 +-
 .../rest/cxf/service/PolicyServiceImpl.java     |   6 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |   4 +-
 .../camel/CamelGroupProvisioningManager.java    |   4 +-
 .../camel/CamelUserProvisioningManager.java     |  12 +-
 .../processor/GroupCreateInPullProcessor.java   |  76 ++
 .../processor/GroupCreateInSyncProcessor.java   |  76 --
 .../processor/UserSetStatusInPullProcessor.java |  70 ++
 .../processor/UserSetStatusInSyncProcessor.java |  70 --
 .../processor/UserUpdateInPullProcessor.java    |  62 ++
 .../processor/UserUpdateInSyncProcessor.java    |  66 --
 .../src/main/resources/groupRoutes.xml          |  10 +-
 .../src/main/resources/userRoutes.xml           |  18 +-
 fit/build-tools/src/main/resources/content.ldif |  14 +-
 fit/build-tools/src/main/resources/testdb.sql   |   6 +-
 .../reference/PrefixMappingItemTransformer.java |   4 +-
 .../fit/core/reference/TestPullActions.java     | 101 +++
 .../fit/core/reference/TestPullRule.java        |  40 +
 .../TestReconciliationFilterBuilder.java        |   2 +-
 .../fit/core/reference/TestSyncActions.java     | 101 ---
 .../fit/core/reference/TestSyncRule.java        |  40 -
 .../org/apache/syncope/fit/AbstractITCase.java  |   4 +-
 .../org/apache/syncope/fit/cli/CLIITCase.java   |   4 +
 .../syncope/fit/console/BulkActionITCase.java   |   2 +-
 .../apache/syncope/fit/console/LogsITCase.java  |   2 +
 .../syncope/fit/console/ParametersITCase.java   |   2 +
 .../apache/syncope/fit/console/RolesITCase.java |   2 +
 .../fit/console/SecurityQuestionsITCase.java    |   3 +
 .../syncope/fit/console/TopologyITCase.java     |   6 +-
 .../syncope/fit/core/AbstractTaskITCase.java    |   2 +-
 .../apache/syncope/fit/core/LoggerITCase.java   |   4 +-
 .../syncope/fit/core/MultitenancyITCase.java    |  20 +-
 .../apache/syncope/fit/core/PolicyITCase.java   |  40 +-
 .../apache/syncope/fit/core/PullTaskITCase.java | 853 ++++++++++++++++++
 .../syncope/fit/core/ReportTemplateITCase.java  |   6 -
 .../apache/syncope/fit/core/ResourceITCase.java |   4 +-
 .../syncope/fit/core/SchedTaskITCase.java       |   4 +-
 .../apache/syncope/fit/core/SearchITCase.java   |  24 +-
 .../apache/syncope/fit/core/SyncTaskITCase.java | 854 -------------------
 .../apache/syncope/fit/core/VirAttrITCase.java  |  14 +-
 src/main/asciidoc/concepts/concepts.adoc        |   4 +-
 .../concepts/provisioning/provisioning.adoc     |   6 +-
 .../asciidoc/concepts/provisioning/pull.adoc    |  52 ++
 .../concepts/provisioning/resources.adoc        |   4 +-
 .../asciidoc/concepts/provisioning/sync.adoc    |  52 --
 .../workingwithapachesyncope/cli/task.adoc      |   2 +-
 236 files changed, 7707 insertions(+), 7700 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
index bae4b88..81d5014 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
@@ -183,18 +183,18 @@ public class Info {
         }
     }
 
-    public void syncActions() {
+    public void pullActions() {
         try {
-            infoResultManager.printSyncActions(platformInfo.getSyncActions());
+            infoResultManager.printPullActions(platformInfo.getPullActions());
         } catch (final Exception ex) {
             LOG.error("Information error", ex);
             infoResultManager.genericError(ex.getMessage());
         }
     }
 
-    public void syncCorrelationRules() {
+    public void pullCorrelationRules() {
         try {
-            infoResultManager.printCorrelationRules(platformInfo.getSyncCorrelationRules());
+            infoResultManager.printCorrelationRules(platformInfo.getPullCorrelationRules());
         } catch (final Exception ex) {
             LOG.error("Information error", ex);
             infoResultManager.genericError(ex.getMessage());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java
index 1991fdd..60ed46a 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoCommand.java
@@ -86,10 +86,10 @@ public class InfoCommand extends AbstractCommand {
                 info.reportlets();
                 break;
             case SYNC_ACTIONS:
-                info.syncActions();
+                info.pullActions();
                 break;
             case SYNC_CORRELATION_RULES:
-                info.syncCorrelationRules();
+                info.pullCorrelationRules();
                 break;
             case TASK_JOBS:
                 info.taskJobs();

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java
index 4494d86..964469e 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/InfoResultManager.java
@@ -111,7 +111,7 @@ public class InfoResultManager extends CommonsResultManager {
         }
     }
 
-    public void printSyncActions(final Collection<String> actions) {
+    public void printPullActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Sync action: " + action);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyDetails.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyDetails.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyDetails.java
index 077ab45..faa8270 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyDetails.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyDetails.java
@@ -43,15 +43,15 @@ public class PolicyDetails extends AbstractPolicyCommand {
                 final Map<String, String> details = new LinkedMap<>();
                 final int accountPolicySize = policySyncopeOperations.list(PolicyType.ACCOUNT.name()).size();
                 final int passwordPolicySize = policySyncopeOperations.list(PolicyType.PASSWORD.name()).size();
-                final int syncPolicySize = policySyncopeOperations.list(PolicyType.SYNC.name()).size();
+                final int pullPolicySize = policySyncopeOperations.list(PolicyType.PULL.name()).size();
                 final int pushPolicySize = policySyncopeOperations.list(PolicyType.PUSH.name()).size();
                 details.put("total number", String.valueOf(accountPolicySize
                         + passwordPolicySize
-                        + syncPolicySize
+                        + pullPolicySize
                         + pushPolicySize));
                 details.put("account policies", String.valueOf(accountPolicySize));
                 details.put("password policies", String.valueOf(passwordPolicySize));
-                details.put("sync policies", String.valueOf(syncPolicySize));
+                details.put("pull policies", String.valueOf(pullPolicySize));
                 details.put("push policies", String.valueOf(pushPolicySize));
                 policyResultManager.printDetails(details);
             } catch (final Exception ex) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyResultManager.java
index acd7eb3..d0432f3 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/policy/PolicyResultManager.java
@@ -24,7 +24,7 @@ import org.apache.syncope.client.cli.commands.CommonsResultManager;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
 
 public class PolicyResultManager extends CommonsResultManager {
@@ -44,8 +44,8 @@ public class PolicyResultManager extends CommonsResultManager {
                     case PUSH:
                         System.out.println(policyTO);
                         break;
-                    case SYNC:
-                        printSyncPolicy((SyncPolicyTO) policyTO);
+                    case PULL:
+                        printPullPolicy((PullPolicyTO) policyTO);
                         break;
                     default:
                         break;
@@ -74,9 +74,9 @@ public class PolicyResultManager extends CommonsResultManager {
                     System.out.println(policyTO);
                 }
                 break;
-            case SYNC:
+            case PULL:
                 for (final AbstractPolicyTO policyTO : policyTOs) {
-                    printSyncPolicy((SyncPolicyTO) policyTO);
+                    printPullPolicy((PullPolicyTO) policyTO);
                 }
                 break;
             default:
@@ -110,7 +110,7 @@ public class PolicyResultManager extends CommonsResultManager {
         System.out.println("");
     }
 
-    public void printSyncPolicy(final SyncPolicyTO policyTO) {
+    public void printPullPolicy(final PullPolicyTO policyTO) {
         System.out.println(" > KEY: " + policyTO.getKey());
         System.out.println("    type: " + policyTO.getType().name());
         System.out.println("    description: " + policyTO.getDescription());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
index 9893a95..18ab0aa 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
@@ -42,7 +42,7 @@ public class ResourceResultManager extends CommonsResultManager {
         System.out.println("    connector id: " + resourceTO.getConnector());
         System.out.println("    account policy id: " + resourceTO.getAccountPolicy());
         System.out.println("    password policy id: " + resourceTO.getPasswordPolicy());
-        System.out.println("    sync policy id: " + resourceTO.getSyncPolicy());
+        System.out.println("    pull policy id: " + resourceTO.getPullPolicy());
         System.out.println("    creator: " + resourceTO.getCreator());
         System.out.println("    creation date: " + resourceTO.getCreationDate());
         System.out.println("    last modifier: " + resourceTO.getLastModifier());
@@ -54,7 +54,7 @@ public class ResourceResultManager extends CommonsResultManager {
         System.out.println("    create trace level: " + resourceTO.getCreateTraceLevel());
         System.out.println("    delete trace level: " + resourceTO.getDeleteTraceLevel());
         System.out.println("    update trace level: " + resourceTO.getUpdateTraceLevel());
-        System.out.println("    sync trace level: " + resourceTO.getSyncTraceLevel());
+        System.out.println("    pull trace level: " + resourceTO.getPullTraceLevel());
         System.out.println("    enforce mandatory condition: " + resourceTO.isEnforceMandatoryCondition());
         System.out.println("    override capabilities: " + resourceTO.isOverrideCapabilities());
         System.out.println("    random password if not provided: " + resourceTO.isRandomPwdIfNotProvided());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java
index 45fd01c..bb00255 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskDetails.java
@@ -30,8 +30,8 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,27 +57,24 @@ public class TaskDetails extends AbstractTaskCommand {
                 final List<AbstractTaskTO> propagationTaskTOs = taskSyncopeOperations.list(TaskType.PROPAGATION.name());
                 final List<AbstractTaskTO> pushTaskTOs = taskSyncopeOperations.list(TaskType.PUSH.name());
                 final List<AbstractTaskTO> scheduledTaskTOs = taskSyncopeOperations.list(TaskType.SCHEDULED.name());
-                final List<AbstractTaskTO> syncTaskTOs = taskSyncopeOperations.list(TaskType.SYNCHRONIZATION.name());
+                final List<AbstractTaskTO> pullTaskTOs = taskSyncopeOperations.list(TaskType.PULL.name());
                 final List<JobTO> jobTOs = taskSyncopeOperations.listJobs();
                 final int notificationTaskSize = notificationTaskTOs.size();
-                int notificationNotExecuted = 0;
                 final int propagationTaskSize = propagationTaskTOs.size();
-                int propagationNotExecuted = 0;
                 final int pushTaskSize = pushTaskTOs.size();
-                int pushNotExecuted = 0;
                 final int scheduledTaskSize = scheduledTaskTOs.size();
                 int scheduledNotExecuted = 0;
-                final int syncTaskSize = syncTaskTOs.size();
-                int syncNotExecuted = 0;
-                int syncFull = 0;
+                final int pullTaskSize = pullTaskTOs.size();
                 final int jobsSize = jobTOs.size();
 
+                int notificationNotExecuted = 0;
                 for (final AbstractTaskTO notificationTaskTO : notificationTaskTOs) {
                     if (!((NotificationTaskTO) notificationTaskTO).isExecuted()) {
                         notificationNotExecuted++;
                     }
                 }
 
+                int propagationNotExecuted = 0;
                 for (final AbstractTaskTO propagationTaskTO : propagationTaskTOs) {
                     if (((PropagationTaskTO) propagationTaskTO).getExecutions() == null
                             || ((PropagationTaskTO) propagationTaskTO).getExecutions().isEmpty()) {
@@ -85,6 +82,7 @@ public class TaskDetails extends AbstractTaskCommand {
                     }
                 }
 
+                int pushNotExecuted = 0;
                 for (final AbstractTaskTO pushTaskTO : pushTaskTOs) {
                     if (((PushTaskTO) pushTaskTO).getExecutions() == null
                             || ((PushTaskTO) pushTaskTO).getExecutions().isEmpty()) {
@@ -99,13 +97,15 @@ public class TaskDetails extends AbstractTaskCommand {
                     }
                 }
 
-                for (final AbstractTaskTO syncTaskTO : syncTaskTOs) {
-                    if (((SyncTaskTO) syncTaskTO).getExecutions() == null
-                            || ((SyncTaskTO) syncTaskTO).getExecutions().isEmpty()) {
-                        syncNotExecuted++;
+                int pullNotExecuted = 0;
+                int pullFull = 0;
+                for (final AbstractTaskTO pullTaskTO : pullTaskTOs) {
+                    if (((PullTaskTO) pullTaskTO).getExecutions() == null
+                            || ((PullTaskTO) pullTaskTO).getExecutions().isEmpty()) {
+                        pullNotExecuted++;
                     }
-                    if (((SyncTaskTO) syncTaskTO).getSyncMode() == SyncMode.FULL_RECONCILIATION) {
-                        syncFull++;
+                    if (((PullTaskTO) pullTaskTO).getPullMode() == PullMode.FULL_RECONCILIATION) {
+                        pullFull++;
                     }
                 }
 
@@ -113,7 +113,7 @@ public class TaskDetails extends AbstractTaskCommand {
                         + propagationTaskSize
                         + pushTaskSize
                         + scheduledTaskSize
-                        + syncTaskSize));
+                        + pullTaskSize));
                 details.put("notification tasks", String.valueOf(notificationTaskSize));
                 details.put("notification tasks not executed", String.valueOf(notificationNotExecuted));
                 details.put("propagation tasks", String.valueOf(propagationTaskSize));
@@ -122,9 +122,9 @@ public class TaskDetails extends AbstractTaskCommand {
                 details.put("push tasks not executed", String.valueOf(pushNotExecuted));
                 details.put("scheduled tasks", String.valueOf(scheduledTaskSize));
                 details.put("scheduled tasks not executed", String.valueOf(scheduledNotExecuted));
-                details.put("synchronization tasks", String.valueOf(syncTaskSize));
-                details.put("synchronization tasks not executed", String.valueOf(syncNotExecuted));
-                details.put("synchronization tasks with full reconciliation", String.valueOf(syncFull));
+                details.put("pull tasks", String.valueOf(pullTaskSize));
+                details.put("pull tasks not executed", String.valueOf(pullNotExecuted));
+                details.put("pull tasks with full reconciliation", String.valueOf(pullFull));
                 details.put("jobs", String.valueOf(jobsSize));
                 taskResultManager.printDetails(details);
             } catch (final SyncopeClientException ex) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskList.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskList.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskList.java
index 02a22b0..90b9cf8 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskList.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskList.java
@@ -32,7 +32,7 @@ public class TaskList extends AbstractTaskCommand {
     private static final Logger LOG = LoggerFactory.getLogger(TaskList.class);
 
     private static final String LIST_HELP_MESSAGE = "task --list {TASK-TYPE}\n"
-            + "   Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / SYNCHRONIZATION";
+            + "   Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / PULL";
 
     private final Input input;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
index ed5b977..df7d081 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/task/TaskResultManager.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.TaskType;
 
@@ -46,8 +46,8 @@ public class TaskResultManager extends CommonsResultManager {
                 printPushTask((PushTaskTO) taskTO);
             } else if (taskTO instanceof SchedTaskTO) {
                 printScheduledTask((SchedTaskTO) taskTO);
-            } else if (taskTO instanceof SyncTaskTO) {
-                printSyncTask((SyncTaskTO) taskTO);
+            } else if (taskTO instanceof PullTaskTO) {
+                printPullTask((PullTaskTO) taskTO);
             }
         }
     }
@@ -75,9 +75,9 @@ public class TaskResultManager extends CommonsResultManager {
                     printScheduledTask((SchedTaskTO) taskTO);
                 }
                 break;
-            case SYNCHRONIZATION:
+            case PULL:
                 for (final AbstractTaskTO taskTO : taskTOs) {
-                    printSyncTask((SyncTaskTO) taskTO);
+                    printPullTask((PullTaskTO) taskTO);
                 }
                 break;
             default:
@@ -127,7 +127,7 @@ public class TaskResultManager extends CommonsResultManager {
         System.out.println("     is perform create: " + pushTaskTO.isPerformCreate());
         System.out.println("     is perform delete: " + pushTaskTO.isPerformDelete());
         System.out.println("     is perform update: " + pushTaskTO.isPerformUpdate());
-        System.out.println("     is sync status: " + pushTaskTO.isSyncStatus());
+        System.out.println("     is pull status: " + pushTaskTO.isPullStatus());
         System.out.println("     start date: " + pushTaskTO.getStart());
         System.out.println("     end date: " + pushTaskTO.getEnd());
         System.out.println("     last execution: " + pushTaskTO.getLastExec());
@@ -157,30 +157,30 @@ public class TaskResultManager extends CommonsResultManager {
         System.out.println("");
     }
 
-    private void printSyncTask(final SyncTaskTO syncTaskTO) {
-        System.out.println(" - Sync task key: " + syncTaskTO.getKey());
-        System.out.println("     name: " + syncTaskTO.getName());
-        System.out.println("     resource: " + syncTaskTO.getResource());
-        System.out.println("     realm destination: " + syncTaskTO.getDestinationRealm());
-        System.out.println("     cron expression: " + syncTaskTO.getCronExpression());
-        System.out.println("     description: " + syncTaskTO.getDescription());
-        System.out.println("     sync mode: " + syncTaskTO.getSyncMode());
-        System.out.println("     perform create: " + syncTaskTO.isPerformCreate());
-        System.out.println("     perform delete: " + syncTaskTO.isPerformDelete());
-        System.out.println("     perform update: " + syncTaskTO.isPerformUpdate());
-        System.out.println("     sync status: " + syncTaskTO.isSyncStatus());
+    private void printPullTask(final PullTaskTO pullTaskTO) {
+        System.out.println(" - Pull task key: " + pullTaskTO.getKey());
+        System.out.println("     name: " + pullTaskTO.getName());
+        System.out.println("     resource: " + pullTaskTO.getResource());
+        System.out.println("     realm destination: " + pullTaskTO.getDestinationRealm());
+        System.out.println("     cron expression: " + pullTaskTO.getCronExpression());
+        System.out.println("     description: " + pullTaskTO.getDescription());
+        System.out.println("     pull mode: " + pullTaskTO.getPullMode());
+        System.out.println("     perform create: " + pullTaskTO.isPerformCreate());
+        System.out.println("     perform delete: " + pullTaskTO.isPerformDelete());
+        System.out.println("     perform update: " + pullTaskTO.isPerformUpdate());
+        System.out.println("     pull status: " + pullTaskTO.isPullStatus());
         System.out.println("     TEMPLATES:");
-        printTemplates(syncTaskTO.getTemplates());
-        System.out.println("     start date: " + syncTaskTO.getStart());
-        System.out.println("     end date: " + syncTaskTO.getEnd());
-        System.out.println("     next execution: " + syncTaskTO.getNextExec());
-        System.out.println("     last execution: " + syncTaskTO.getLastExec());
-        System.out.println("     latest execution status: " + syncTaskTO.getLatestExecStatus());
-        System.out.println("     job delegate class: " + syncTaskTO.getJobDelegateClassName());
-        System.out.println("     action class name: " + syncTaskTO.getActionsClassNames());
-        System.out.println("     matching rule: " + syncTaskTO.getMatchingRule());
-        System.out.println("     unmatching rule: " + syncTaskTO.getUnmatchingRule());
-        printTaskExecTOs(syncTaskTO.getExecutions());
+        printTemplates(pullTaskTO.getTemplates());
+        System.out.println("     start date: " + pullTaskTO.getStart());
+        System.out.println("     end date: " + pullTaskTO.getEnd());
+        System.out.println("     next execution: " + pullTaskTO.getNextExec());
+        System.out.println("     last execution: " + pullTaskTO.getLastExec());
+        System.out.println("     latest execution status: " + pullTaskTO.getLatestExecStatus());
+        System.out.println("     job delegate class: " + pullTaskTO.getJobDelegateClassName());
+        System.out.println("     action class name: " + pullTaskTO.getActionsClassNames());
+        System.out.println("     matching rule: " + pullTaskTO.getMatchingRule());
+        System.out.println("     unmatching rule: " + pullTaskTO.getUnmatchingRule());
+        printTaskExecTOs(pullTaskTO.getExecutions());
         System.out.println("");
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/cli/src/main/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/cli/src/main/resources/messages.properties b/client/cli/src/main/resources/messages.properties
index 9ffa1cf..8b5daf2 100644
--- a/client/cli/src/main/resources/messages.properties
+++ b/client/cli/src/main/resources/messages.properties
@@ -22,13 +22,13 @@ entitlement.help.message=\nUsage: entitlement [options]\n  Options:\n    --help
 group.help.message=\nUsage: group [options]\n  Options:\n    --help \n    --details \n    --list \n    --read \n       Syntax: --read {GROUP-ID} {GROUP-ID} [...]\n    --read-attr-by-schema-type {GROUP-ID} {SCHEMA-TYPE}\n       Schema type: PLAIN / DERIVED / VIRTUAL\n    --read-attr-by-schema {GROUP-ID} {SCHEMA-TYPE} {SCHEMA-NAME}\n       Schema type: PLAIN / DERIVED / VIRTUAL\n    --delete \n       Syntax: --delete {GROUP-ID} {GROUP-ID} [...]\n
 logger.help.message=\nUsage: logger [options]\n  Options:\n    --help \n    --details \n    --list \n    --read \n       Syntax: --read {LOG-NAME} {LOG-NAME} [...]\n    --update \n       Syntax: --update {LOG-NAME}={LOG-LEVEL} {LOG-NAME}={LOG-LEVEL} [...]\n    --update-all \n       Syntax: --update-all {LOG-LEVEL} \n    --create \n       Syntax: --create {LOG-NAME}={LOG-LEVEL} {LOG-NAME}={LOG-LEVEL} [...]\n    --delete \n       Syntax: --delete {LOG-NAME} {LOG-NAME} [...]\n
 notification.help.message=\nUsage: notification [options]\n  Options:\n    --help \n    --list \n    --read \n       Syntax: --read {NOTIFICATION-ID} \n    --delete \n       Syntax: --delete {NOTIFICATION-ID}\n
-policy.help.message=\nUsage: policy [options]\n  Options:\n    --help \n    --details \n    --list \n       Syntax: --list-policy {POLICY-TYPE} \n          Policy type: ACCOUNT / PASSWORD / SYNC / PUSH\n    --read \n       Syntax: --read {POLICY-ID} {POLICY-ID} [...]\n    --delete \n       Syntax: --delete {POLICY-ID} {POLICY-ID} [...]\n
+policy.help.message=\nUsage: policy [options]\n  Options:\n    --help \n    --details \n    --list \n       Syntax: --list-policy {POLICY-TYPE} \n          Policy type: ACCOUNT / PASSWORD / PULL / PUSH\n    --read \n       Syntax: --read {POLICY-ID} {POLICY-ID} [...]\n    --delete \n       Syntax: --delete {POLICY-ID} {POLICY-ID} [...]\n
 question.help.message=\nUsage: question [options]\n  Options:\n    --help \n    --list \n    --read \n       Syntax: --read {QUESTION-ID} {QUESTION-ID} [...]\n    --delete \n       Syntax: --delete {QUESTION-ID} {QUESTION-ID} [...]\n
 realm.help.message=\nUsage: realm [options]\n  Options:\n    --help \n    --details \n    --list \n
 report.help.message=\nUsage: report [options]\n  Options:\n    --help \n    --details\n    --list \n    --list-jobs \n    --read \n       Syntax: --read {REPORT-ID} {REPORT-ID} [...] \n    --delete \n       Syntax: --delete {REPORT-ID} {REPORT-ID} [...]\n    --execute \n       Syntax: --execute {REPORT-ID} \n    --delete-execution \n       Syntax: --delete-execution {EXECUTION-ID} {EXECUTION-ID} [...]\n    --export-execution-result \n       Syntax: --export-execution-result {EXECUTION-ID} {EXECUTION-ID} [...] {FORMAT}\n          Format: CSV / HTML / PDF / XML / RTF\n
 resource.help.message=\nUsage: resource [options]\n  Options:\n    --help \n    --details \n    --list \n    --read \n       Syntax: --read {RESOURCE-NAME} {RESOURCE-NAME} [...]\n    --delete \n       Syntax: --delete {RESOURCE-NAME} {RESOURCE-NAME} [...]\n
 role.help.message=\nUsage: role [options]\n  Options:\n    --help \n    --details \n    --list \n    --read \n       Syntax: --read {ROLE-ID} {ROLE-ID} [...]\n    --delete \n       Syntax: --delete {ROLE-ID} {ROLE-ID} [...]\n
 schema.help.message=\nUsage: schema [options]\n  Options:\n    --help \n    --details \n    --list-all\n    --list-plain\n    --list-derived\n    --list-virtual\n    --read {SCHEMA-TYPE} {SCHEMA-KEY}\n        Schema type: PLAIN / DERIVED / VIRTUAL\n    --delete {SCHEMA-TYPE} {SCHEMA-KEY}\n        Schema type: PLAIN / DERIVED / VIRTUAL\n
-task.help.message=\nUsage: task [options]\n  Options:\n    --help \n    --details\n    --list\n       Syntax: --list {TASK-TYPE} \n          Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / SYNCHRONIZATION\n    --list-running-jobs \n    --list-scheduled-jobs \n    --read \n       Syntax: --read {TASK-ID} {TASK-ID} [...]\n    --delete \n       Syntax: --delete {TASK-ID} {TASK-ID} [...]\n    --delete-all-prop\n    --delete-execution \n       Syntax: --delete-execution {TASK-EXEC-ID} {TASK-EXEC-ID} [...]\n    --execute \n       Syntax: --execute {TASK-ID} {DRY-RUN}\n          Dry run: true / false\n
+task.help.message=\nUsage: task [options]\n  Options:\n    --help \n    --details\n    --list\n       Syntax: --list {TASK-TYPE} \n          Task type: NOTIFICATION / PROPAGATION / PUSH / SCHEDULED / PULL\n    --list-running-jobs \n    --list-scheduled-jobs \n    --read \n       Syntax: --read {TASK-ID} {TASK-ID} [...]\n    --delete \n       Syntax: --delete {TASK-ID} {TASK-ID} [...]\n    --delete-all-prop\n    --delete-execution \n       Syntax: --delete-execution {TASK-EXEC-ID} {TASK-EXEC-ID} [...]\n    --execute \n       Syntax: --execute {TASK-ID} {DRY-RUN}\n          Dry run: true / false\n
 user.help.message=\nUsage: user [options]\n  Options:\n    --help \n    --details \n    --list \n    --get-user-key\n       Syntax: --get-user-key {USERNAME}\n    --get-username\n       Syntax: --get-username {USER-ID}\n    --read-by-userid \n       Syntax: --read-by-userid {USER-ID} {USER-ID} [...]\n    --read-by-username\n       Syntax: --read-by-username {USERNAME} {USERNAME} [...]\n    --search-by-attribute \n       Syntax: --search-by-attribute {REALM} {ATTR-NAME}={ATTR-VALUE}\n    --search-by-role \n       Syntax: --search-by-role {REALM} {ROLE-NAME}\n    --search-by-resource \n       Syntax: --search-by-resource {REALM} {RESOURCE-NAME}\n    --delete \n       Syntax: --delete {USER-ID} {USER-ID} [...]\n    --delete-all \n       Syntax: --delete-all {REALM}\n    --delete-by-attribute \n       Syntax: --delete-by-attribute {REALM} {ATTR-NAME}={ATTR-VALUE}\n
 workflow.help.message=\nUsage: workflow [options]\n  Options:\n    --help \n    --export-diagram {ANY-TYPE-KIND}\n        Any type kind: ANY_OBJECT / USER / GROUP\n    --export-definition {ANY-TYPE-KIND}\n        Any type kind: ANY_OBJECT / USER / GROUP\n

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index 2a508d1..3e0d4a4 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -102,7 +102,7 @@ public final class Constants {
 
     public static final String PREF_SCHED_TASKS_PAGINATOR_ROWS = "schedtasks.paginator.rows";
 
-    public static final String PREF_SYNC_TASKS_PAGINATOR_ROWS = "synctasks.paginator.rows";
+    public static final String PREF_PULL_TASKS_PAGINATOR_ROWS = "pulltasks.paginator.rows";
 
     public static final String PREF_PUSH_TASKS_PAGINATOR_ROWS = "pushtasks.paginator.rows";
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
index 0613296..24fda22 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
@@ -178,13 +178,13 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
                     compared = 1;
                 } else if (left.getPurpose() == MappingPurpose.PROPAGATION
-                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                        && (right.getPurpose() == MappingPurpose.PULL
                         || right.getPurpose() == MappingPurpose.NONE)) {
                     compared = -1;
-                } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                } else if (left.getPurpose() == MappingPurpose.PULL
                         && right.getPurpose() == MappingPurpose.PROPAGATION) {
                     compared = 1;
-                } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                } else if (left.getPurpose() == MappingPurpose.PULL
                         && right.getPurpose() == MappingPurpose.NONE) {
                     compared = -1;
                 } else if (left.getPurpose() == MappingPurpose.NONE

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
index 4d90788..ad56e9e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java
@@ -45,7 +45,7 @@ public class ResourceSecurityPanel extends Panel {
 
     private IModel<Map<Long, String>> accountPolicies = null;
 
-    private IModel<Map<Long, String>> syncPolicies = null;
+    private IModel<Map<Long, String>> pullPolicies = null;
 
     public ResourceSecurityPanel(final String id, final IModel<ResourceTO> model) {
 
@@ -86,14 +86,14 @@ public class ResourceSecurityPanel extends Panel {
             }
         };
 
-        syncPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+        pullPolicies = new LoadableDetachableModel<Map<Long, String>>() {
 
             private static final long serialVersionUID = -2012833443695917883L;
 
             @Override
             protected Map<Long, String> load() {
                 Map<Long, String> res = new HashMap<>();
-                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.SYNC)) {
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.PULL)) {
                     res.put(policyTO.getKey(), policyTO.getDescription());
                 }
                 return res;
@@ -131,18 +131,18 @@ public class ResourceSecurityPanel extends Panel {
         // -------------------------------
 
         // -------------------------------
-        // Sync policy specification
+        // Pull policy specification
         // -------------------------------
-        final AjaxDropDownChoicePanel<Long> syncPolicy = new AjaxDropDownChoicePanel<Long>(
-                "syncPolicy",
-                new ResourceModel("syncPolicy", "syncPolicy").getObject(),
-                new PropertyModel<Long>(model, "syncPolicy"),
+        AjaxDropDownChoicePanel<Long> pullPolicy = new AjaxDropDownChoicePanel<>(
+                "pullPolicy",
+                new ResourceModel("pullPolicy", "pullPolicy").getObject(),
+                new PropertyModel<Long>(model, "pullPolicy"),
                 false);
 
-        syncPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.SYNC));
-        syncPolicy.setChoices(new ArrayList<Long>(syncPolicies.getObject().keySet()));
-        ((DropDownChoice<?>) syncPolicy.getField()).setNullValid(true);
-        container.add(syncPolicy);
+        pullPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.PULL));
+        pullPolicy.setChoices(new ArrayList<Long>(pullPolicies.getObject().keySet()));
+        ((DropDownChoice<?>) pullPolicy.getField()).setNullValid(true);
+        container.add(pullPolicy);
         // -------------------------------
     }
 
@@ -164,8 +164,8 @@ public class ResourceSecurityPanel extends Panel {
                     return accountPolicies.getObject().get(object);
                 case PASSWORD:
                     return passwordPolicies.getObject().get(object);
-                case SYNC:
-                    return syncPolicies.getObject().get(object);
+                case PULL:
+                    return pullPolicies.getObject().get(object);
                 default:
                     return "";
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
index 11ec127..0d80b45 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
@@ -72,7 +72,7 @@ public class PolicyRestClient extends BaseRestClient {
         Set<String> rules = null;
 
         try {
-            rules = SyncopeConsoleSession.get().getPlatformInfo().getSyncCorrelationRules();
+            rules = SyncopeConsoleSession.get().getPlatformInfo().getPullCorrelationRules();
         } catch (Exception e) {
             LOG.error("While getting all correlation rule classes", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
index 2338911..54bc352 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
@@ -49,8 +49,8 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
         return SyncopeConsoleSession.get().getPlatformInfo().getTaskJobs();
     }
 
-    public Set<String> getSyncActionsClasses() {
-        return SyncopeConsoleSession.get().getPlatformInfo().getSyncActions();
+    public Set<String> getPullActionsClasses() {
+        return SyncopeConsoleSession.get().getPlatformInfo().getPullActions();
     }
 
     public Set<String> getPushActionsClasses() {
@@ -126,8 +126,8 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
             result = TaskType.NOTIFICATION;
         } else if (SchedTaskTO.class.equals(reference)) {
             result = TaskType.SCHEDULED;
-        } else if (SyncTaskTO.class.equals(reference)) {
-            result = TaskType.SYNCHRONIZATION;
+        } else if (PullTaskTO.class.equals(reference)) {
+            result = TaskType.PULL;
         } else if (PushTaskTO.class.equals(reference)) {
             result = TaskType.PUSH;
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
index deb0af5..c0c85e2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ProvisioningTaskSearchResultPanel.java
@@ -26,7 +26,7 @@ import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.to.AbstractProvisioningTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -78,7 +78,7 @@ public abstract class ProvisioningTaskSearchResultPanel<T extends AbstractProvis
         columns.add(new PropertyColumn<T, String>(
                 new StringResourceModel("description", this, null), "description", "description"));
 
-        if (reference == SyncTaskTO.class) {
+        if (reference == PullTaskTO.class) {
             columns.add(new PropertyColumn<T, String>(
                     new StringResourceModel("destinationRealm", this, null), "destinationRealm", "destinationRealm"));
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskSearchResultPanel.java
new file mode 100644
index 0000000..dd01779
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTaskSearchResultPanel.java
@@ -0,0 +1,49 @@
+/*
+ * 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.client.console.tasks;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.wicket.PageReference;
+
+public abstract class PullTaskSearchResultPanel extends ProvisioningTaskSearchResultPanel<PullTaskTO> {
+
+    private static final long serialVersionUID = 4984337552918213290L;
+
+    protected PullTaskSearchResultPanel(
+            final BaseModal<?> baseModal,
+            final MultilevelPanel multiLevelPanelRef,
+            final String resource,
+            final PageReference pageRef) {
+        super(baseModal, multiLevelPanelRef, PullTaskTO.class, resource, pageRef);
+    }
+
+    @Override
+    protected String paginatorRowsKey() {
+        return Constants.PREF_PUSH_TASKS_PAGINATOR_ROWS;
+    }
+
+    @Override
+    protected ProvisioningTasksProvider<PullTaskTO> dataProvider() {
+        return new ProvisioningTasksProvider<>(reference, TaskType.PULL, rows);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
new file mode 100644
index 0000000..559469b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/PullTasks.java
@@ -0,0 +1,53 @@
+/*
+ * 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.client.console.tasks;
+
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.StringResourceModel;
+
+public class PullTasks extends AbstractTasks {
+
+    private static final long serialVersionUID = -4013796607157549641L;
+
+    public <T extends AnyTO> PullTasks(
+            final BaseModal<?> baseModal, final PageReference pageReference, final String resource) {
+        super(BaseModal.CONTENT_ID);
+
+        final MultilevelPanel mlp = new MultilevelPanel("tasks");
+        add(mlp);
+
+        mlp.setFirstLevel(new PullTaskSearchResultPanel(baseModal, mlp, resource, pageReference) {
+
+            private static final long serialVersionUID = -2195387360323687302L;
+
+            @Override
+            protected void viewTask(final PullTaskTO taskTO, final AjaxRequestTarget target) {
+                mlp.next(
+                        new StringResourceModel("task.view", this, new Model<>(taskTO)).getObject(),
+                        new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
index b7bd69c..6fc3fdd 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
@@ -31,9 +31,9 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPa
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
 import org.apache.syncope.common.lib.to.AbstractProvisioningTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.SyncMode;
+import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -107,42 +107,42 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
                     new PropertyModel<Boolean>(taskTO, "active"), false);
             add(active);
 
-            final WebMarkupContainer syncTaskSpecifics = new WebMarkupContainer("syncTaskSpecifics");
-            add(syncTaskSpecifics.setRenderBodyOnly(true));
+            final WebMarkupContainer pullTaskSpecifics = new WebMarkupContainer("pullTaskSpecifics");
+            add(pullTaskSpecifics.setRenderBodyOnly(true));
 
             boolean isFiltered = false;
 
-            if (taskTO instanceof SyncTaskTO) {
-                isFiltered = SyncTaskTO.class.cast(taskTO).getSyncMode() == SyncMode.FILTERED_RECONCILIATION;
+            if (taskTO instanceof PullTaskTO) {
+                isFiltered = PullTaskTO.class.cast(taskTO).getPullMode() == PullMode.FILTERED_RECONCILIATION;
             } else {
-                syncTaskSpecifics.setEnabled(false).setVisible(false);
+                pullTaskSpecifics.setEnabled(false).setVisible(false);
             }
 
-            final AjaxDropDownChoicePanel<SyncMode> syncMode = new AjaxDropDownChoicePanel<>("syncMode", "syncMode",
-                    new PropertyModel<SyncMode>(taskTO, "syncMode"), false);
-            syncTaskSpecifics.add(syncMode);
-            syncMode.setChoices(Arrays.asList(SyncMode.values()));
+            final AjaxDropDownChoicePanel<PullMode> pullMode = new AjaxDropDownChoicePanel<>("pullMode", "pullMode",
+                    new PropertyModel<PullMode>(taskTO, "pullMode"), false);
+            pullTaskSpecifics.add(pullMode);
+            pullMode.setChoices(Arrays.asList(PullMode.values()));
 
             final AjaxTextFieldPanel filter = new AjaxTextFieldPanel(
                     "reconciliationFilterBuilderClassName", "reconciliationFilterBuilderClassName",
                     new PropertyModel<String>(taskTO, "reconciliationFilterBuilderClassName"), false);
-            syncTaskSpecifics.add(filter);
+            pullTaskSpecifics.add(filter);
             filter.setEnabled(isFiltered);
 
-            syncMode.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+            pullMode.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
                 private static final long serialVersionUID = -1107858522700306810L;
 
                 @Override
                 protected void onUpdate(final AjaxRequestTarget target) {
-                    filter.setEnabled(syncMode.getModelObject() == SyncMode.FILTERED_RECONCILIATION);
+                    filter.setEnabled(pullMode.getModelObject() == PullMode.FILTERED_RECONCILIATION);
                     target.add(filter);
                 }
             });
 
             final AjaxTextFieldPanel destinationRealm = new AjaxTextFieldPanel("destinationRealm", "destinationRealm",
                     new PropertyModel<String>(taskTO, "destinationRealm"), false);
-            syncTaskSpecifics.add(destinationRealm);
+            pullTaskSpecifics.add(destinationRealm);
 
             final AjaxDropDownChoicePanel<String> className = new AjaxDropDownChoicePanel<>(
                     "jobDelegateClassName",
@@ -181,9 +181,9 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
                     "performDelete", "performDelete", new PropertyModel<Boolean>(taskTO, "performDelete"), false);
             provisioningTaskSpecifics.add(performDelete);
 
-            final AjaxCheckBoxPanel syncStatus = new AjaxCheckBoxPanel(
-                    "syncStatus", "syncStatus", new PropertyModel<Boolean>(taskTO, "syncStatus"), false);
-            provisioningTaskSpecifics.add(syncStatus);
+            final AjaxCheckBoxPanel pullStatus = new AjaxCheckBoxPanel(
+                    "pullStatus", "pullStatus", new PropertyModel<Boolean>(taskTO, "pullStatus"), false);
+            provisioningTaskSpecifics.add(pullStatus);
 
             if (taskTO instanceof AbstractProvisioningTaskTO) {
                 className.setEnabled(false).setVisible(false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
deleted file mode 100644
index b0b4f4c..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTaskSearchResultPanel.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.tasks;
-
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.wicket.PageReference;
-
-/**
- * Sync Tasks page.
- */
-public abstract class SyncTaskSearchResultPanel extends ProvisioningTaskSearchResultPanel<SyncTaskTO> {
-
-    private static final long serialVersionUID = 4984337552918213290L;
-
-    protected SyncTaskSearchResultPanel(
-            final BaseModal<?> baseModal,
-            final MultilevelPanel multiLevelPanelRef,
-            final String resource,
-            final PageReference pageRef) {
-        super(baseModal, multiLevelPanelRef, SyncTaskTO.class, resource, pageRef);
-    }
-
-    @Override
-    protected String paginatorRowsKey() {
-        return Constants.PREF_PUSH_TASKS_PAGINATOR_ROWS;
-    }
-
-    @Override
-    protected ProvisioningTasksProvider<SyncTaskTO> dataProvider() {
-        return new ProvisioningTasksProvider<>(reference, TaskType.SYNCHRONIZATION, rows);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
deleted file mode 100644
index b03af35..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SyncTasks.java
+++ /dev/null
@@ -1,53 +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.client.console.tasks;
-
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.StringResourceModel;
-
-public class SyncTasks extends AbstractTasks {
-
-    private static final long serialVersionUID = -4013796607157549641L;
-
-    public <T extends AnyTO> SyncTasks(
-            final BaseModal<?> baseModal, final PageReference pageReference, final String resource) {
-        super(BaseModal.CONTENT_ID);
-
-        final MultilevelPanel mlp = new MultilevelPanel("tasks");
-        add(mlp);
-
-        mlp.setFirstLevel(new SyncTaskSearchResultPanel(baseModal, mlp, resource, pageReference) {
-
-            private static final long serialVersionUID = -2195387360323687302L;
-
-            @Override
-            protected void viewTask(final SyncTaskTO taskTO, final AjaxRequestTarget target) {
-                mlp.next(
-                        new StringResourceModel("task.view", this, new Model<>(taskTO)).getObject(),
-                        new TaskExecutionDetails<>(baseModal, taskTO, pageReference), target);
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index 48f2588..fd495c5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -32,7 +32,7 @@ import org.apache.syncope.client.console.rest.ResourceRestClient;
 import org.apache.syncope.client.console.tasks.PropagationTasks;
 import org.apache.syncope.client.console.tasks.PushTasks;
 import org.apache.syncope.client.console.tasks.SchedTasks;
-import org.apache.syncope.client.console.tasks.SyncTasks;
+import org.apache.syncope.client.console.tasks.PullTasks;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.confirmation.ConfirmationModalBehavior;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -318,19 +318,19 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
         fragment.add(propagation);
         MetaDataRoleAuthorizationStrategy.authorize(propagation, ENABLE, StandardEntitlement.TASK_LIST);
 
-        final AjaxLink<String> synchronization = new IndicatingAjaxLink<String>("synchronization") {
+        final AjaxLink<String> pull = new IndicatingAjaxLink<String>("pull") {
 
             private static final long serialVersionUID = 3776750333491622263L;
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                target.add(taskModal.setContent(new SyncTasks(taskModal, pageRef, node.getKey().toString())));
-                taskModal.header(new ResourceModel("task.synchronization.list", "Synchronization tasks"));
+                target.add(taskModal.setContent(new PullTasks(taskModal, pageRef, node.getKey().toString())));
+                taskModal.header(new ResourceModel("task.pull.list"));
                 taskModal.show(true);
             }
         };
-        fragment.add(synchronization);
-        MetaDataRoleAuthorizationStrategy.authorize(synchronization, ENABLE, StandardEntitlement.TASK_LIST);
+        fragment.add(pull);
+        MetaDataRoleAuthorizationStrategy.authorize(pull, ENABLE, StandardEntitlement.TASK_LIST);
 
         final AjaxLink<String> push = new IndicatingAjaxLink<String>("push") {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java
index 2c41f37..f5d43a6 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java
@@ -33,7 +33,7 @@ public class MappingPurposePanel extends Panel {
 
     private final AjaxLink<Void> propagation;
 
-    private final AjaxLink<Void> synchronization;
+    private final AjaxLink<Void> pull;
 
     private final AjaxLink<Void> both;
 
@@ -56,14 +56,14 @@ public class MappingPurposePanel extends Panel {
             }
         };
 
-        synchronization = new AjaxLink<Void>("synchronizationPurposeLink") {
+        pull = new AjaxLink<Void>("pullPurposeLink") {
 
             private static final long serialVersionUID = -6957616042924610305L;
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                model.setObject(MappingPurpose.SYNCHRONIZATION);
-                setOpacity(MappingPurpose.SYNCHRONIZATION);
+                model.setObject(MappingPurpose.PULL);
+                setOpacity(MappingPurpose.PULL);
                 target.add(container);
             }
         };
@@ -93,7 +93,7 @@ public class MappingPurposePanel extends Panel {
         };
 
         add(propagation);
-        add(synchronization);
+        add(pull);
         add(both);
         add(none);
 
@@ -104,28 +104,32 @@ public class MappingPurposePanel extends Panel {
         switch (mappingPurpose) {
             case PROPAGATION:
                 propagation.add(new AttributeModifier("style", new Model<String>("opacity: 1;")));
-                synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
+                pull.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 break;
-            case SYNCHRONIZATION:
-                synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 1;")));
+
+            case PULL:
+                pull.add(new AttributeModifier("style", new Model<String>("opacity: 1;")));
                 propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 break;
+
             case BOTH:
                 both.add(new AttributeModifier("style", new Model<String>("opacity: 1;")));
                 propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
-                synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
+                pull.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 break;
+
             case NONE:
                 none.add(new AttributeModifier("style", new Model<String>("opacity: 1;")));
-                synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
+                pull.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;")));
                 break;
+
             default:
             // do nothing
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal.properties
index 351d029..fd3fdce 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal.properties
@@ -49,7 +49,7 @@ enable=Enable
 createTraceLevel=Create trace level
 updateTraceLevel=Update trace level
 deleteTraceLevel=Delete trace level
-syncTraceLevel=Synchronization trace level
+pullTraceLevel=Pull trace level
 propagationPriority=Propagation priority
 
 success_connection=Successful connection

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_it.properties
index 51cf18e..6c219f3 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_it.properties
@@ -48,7 +48,7 @@ enable=Abilita
 createTraceLevel=Livello di tracciamento delle creazioni
 updateTraceLevel=Livello di tracciamento degli aggiornamenti
 deleteTraceLevel=Livello di tracciamento delle cancellazioni
-syncTraceLevel=Livello di tracciamento delle sincronizzazioni
+pullTraceLevel=Livello di tracciamento delle pull
 propagationPriority=Priorit\u00e0 in propagazione
 
 success_connection=Connessione avvenuta con successo

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_pt_BR.properties
index 07e0f14..4b2f0a0 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceModal_pt_BR.properties
@@ -48,7 +48,7 @@ enable=Habilitado
 createTraceLevel=Criar n\u00edvel de trace
 updateTraceLevel=Atualizar n\u00edvel de trace
 deleteTraceLevel=Excluir n\u00edvel de trace
-syncTraceLevel=N\u00edvel de trace de sincroniza\u00e7\u00e3o
+pullTraceLevel=N\u00edvel de trace de pull
 propagationPriority=Prioridade de propaga\u00e7\u00e3o
 
 success_connection=Conex\u00e3o com sucesso

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
index 10cfb54..f39d19e 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.html
@@ -25,7 +25,7 @@ under the License.
       <span wicket:id="accountPolicy">
         [panel for dynamic input type markup]
       </span>
-      <span wicket:id="syncPolicy">
+      <span wicket:id="pullPolicy">
         [panel for dynamic input type markup]
       </span>
     </div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
index f7fd440..279e499 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel.properties
@@ -16,4 +16,4 @@
 # under the License.
 passwordPolicy = Password Policy
 accountPolicy = Account Policy
-syncPolicy = Sync Policy
+pullPolicy=Pull Policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
index f7fd440..279e499 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_it.properties
@@ -16,4 +16,4 @@
 # under the License.
 passwordPolicy = Password Policy
 accountPolicy = Account Policy
-syncPolicy = Sync Policy
+pullPolicy=Pull Policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
index 3278665..4c774d5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceSecurityPanel_pt_BR.properties
@@ -16,4 +16,4 @@
 # under the License.
 passwordPolicy = Pol\u00edtica de Senha
 accountPolicy = Pol\u00edtica de Conta
-syncPolicy = Pol\u00edtica de Sincroniza\u00e7\u00e3o
+pullPolicy=Pol\u00edtica de Pull


[09/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
new file mode 100644
index 0000000..c042ec7
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
@@ -0,0 +1,203 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during pull.
+ * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the pull
+ * process.
+ */
+public interface PullActions extends ProvisioningActions {
+
+    /**
+     * Action to be executed before to create a pulled user / group locally.
+     * User/group is created locally upon pull in case of the un-matching rule
+     * {@link org.apache.syncope.common.lib.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeProvision(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before creating (and linking to the resource) a pulled user / group locally.
+     * User/group is created locally and linked to the pulled resource upon pull in case of the
+     * un-matching rule {@link org.apache.syncope.common.lib.types.UnmatchingRule#ASSIGN} is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeAssign(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before unlinking resource from the pulled user / group and de-provisioning.
+     * User/group is unlinked and de-provisioned from the pulled resource upon pull in case of the
+     * matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNASSIGN} is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeUnassign(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before de-provisioning action only.
+     * User/group is de-provisioned (without unlinking) from the pulled resource upon pull in case of
+     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#DEPROVISION} is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeDeprovision(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before unlinking resource from the pulled user / group.
+     * User/group is unlinked (without de-provisioning) from the pulled resource upon pull in case of
+     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNLINK} is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeUnlink(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before linking resource to the pulled user / group.
+     * User/group is linked (without updating) to the pulled resource upon pull in case of
+     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#LINK} is applied.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @return pull information used for user status evaluation and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeLink(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to update a pulled user / group locally.
+     * User/group is updated upon pull in case of the matching rule
+     * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
+     *
+     * @param <M> concrete any object
+     * @param <P> any object modifications
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object
+     * @param anyPatch modification
+     * @return pull information used for logging and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure.
+     */
+    <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            M any,
+            P anyPatch)
+            throws JobExecutionException;
+
+    /**
+     * Action to be executed before to delete a pulled user / group locally.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information
+     * @param any any object to be deleted
+     * @return pull information used for logging and to be passed to the 'after' method.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> SyncDelta beforeDelete(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed when user / group pull goes on error.
+     *
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information (may be modified by
+     * 'beforeProvision/beforeUpdate/beforeDelete')
+     * @param result global pull results at the current pull step
+     * @param error error being reported
+     * @throws JobExecutionException in case of generic failure
+     */
+    void onError(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            ProvisioningReport result,
+            Exception error) throws JobExecutionException;
+
+    /**
+     * Action to be executed after each local user / group pull.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the pull being executed.
+     * @param delta retrieved pull information (may be modified by beforeProvision / beforeUpdate /
+     * beforeDelete)
+     * @param any any object
+     * @param result global pull results at the current pull step
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends AnyTO> void after(
+            ProvisioningProfile<?, ?> profile,
+            SyncDelta delta,
+            A any,
+            ProvisioningReport result) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullCorrelationRule.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullCorrelationRule.java
new file mode 100644
index 0000000..5d6d922
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullCorrelationRule.java
@@ -0,0 +1,36 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+/**
+ * Interface for correlation rule to be evaluated during PullJob execution.
+ */
+public interface PullCorrelationRule {
+
+    /**
+     * Return a search condition.
+     *
+     * @param connObj connector object.
+     * @return search condition.
+     */
+    SearchCond getSearchCond(ConnectorObject connObj);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java
new file mode 100644
index 0000000..93180d4
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java
@@ -0,0 +1,163 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during push.
+ * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
+ */
+public interface PushActions extends ProvisioningActions {
+
+    /**
+     * Action to be executed before to assign (link &amp; provision) a synchronized any object to the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeAssign(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to provision a synchronized any object to the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeProvision(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to update a synchronized any object on the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be updated.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeUpdate(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to link a synchronized any object to the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeLink(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to unlink a synchronized any object from the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeUnlink(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to unassign a synchronized any object from the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeUnassign(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before to unassign a synchronized any object from the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeDeprovision(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed before delete a synchronized any object locally and from the resource.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any any object to be created.
+     * @return any.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> A beforeDelete(
+            ProvisioningProfile<?, ?> profile,
+            A any) throws JobExecutionException;
+
+    /**
+     * Action to be executed after any object push goes on error.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any synchronized any object.
+     * @param result operation result.
+     * @param error error being reported
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> void onError(
+            ProvisioningProfile<?, ?> profile,
+            A any,
+            ProvisioningReport result,
+            Exception error) throws JobExecutionException;
+
+    /**
+     * Action to be executed after each local any object push.
+     *
+     * @param <A> concrete any object
+     * @param profile profile of the push being executed.
+     * @param any synchronized any object.
+     * @param result operation result.
+     * @throws JobExecutionException in case of generic failure
+     */
+    <A extends Any<?>> void after(
+            ProvisioningProfile<?, ?> profile,
+            A any,
+            ProvisioningReport result) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconciliationFilterBuilder.java
new file mode 100644
index 0000000..579e5ca
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconciliationFilterBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.pushpull;
+
+import org.identityconnectors.framework.common.objects.filter.Filter;
+
+/**
+ * Interface to be implemented for performing filtered reconciliation of a
+ * {@link org.apache.syncope.core.persistence.api.entity.task.PullTask}.
+ */
+public interface ReconciliationFilterBuilder {
+
+    Filter build();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullResultHandler.java
new file mode 100644
index 0000000..aa99468
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullResultHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.pushpull;
+
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+
+public interface SyncopePullResultHandler extends SyncopeResultHandler<PullTask, PullActions>, SyncResultsHandler {
+
+    @Override
+    boolean handle(SyncDelta delta);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushResultHandler.java
new file mode 100644
index 0000000..8a32c53
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushResultHandler.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.pushpull;
+
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+
+public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
+
+    boolean handle(long anyKey);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeResultHandler.java
new file mode 100644
index 0000000..16d958f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeResultHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+
+public interface SyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions> {
+
+    ProvisioningProfile<T, A> getProfile();
+
+    void setProfile(ProvisioningProfile<T, A> profile);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPullResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPullResultHandler.java
new file mode 100644
index 0000000..c86420a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPullResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.pushpull;
+
+public interface UserPullResultHandler extends SyncopePullResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPushResultHandler.java
new file mode 100644
index 0000000..f96c0ef
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/UserPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.pushpull;
+
+public interface UserPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
deleted file mode 100644
index 4198b53..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.syncpull;
-
-public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
deleted file mode 100644
index dba6377..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
+++ /dev/null
@@ -1,23 +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.syncpull;
-
-public interface AnyObjectSyncResultHandler extends SyncopeSyncResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
deleted file mode 100644
index 457c78e..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.syncpull;
-
-public interface GroupPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java
deleted file mode 100644
index 19c8b8f..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.syncpull;
-
-import java.util.Map;
-
-public interface GroupSyncResultHandler extends SyncopeSyncResultHandler {
-
-    Map<Long, String> getGroupOwnerMap();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java
deleted file mode 100644
index cdd885a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java
+++ /dev/null
@@ -1,29 +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.syncpull;
-
-/**
- * Raised by {@link SyncActions} or {@link PushActions} methods when the given any object is to be ignored for
- * synchronization / push.
- */
-public class IgnoreProvisionException extends RuntimeException {
-
-    private static final long serialVersionUID = -8803817097998786364L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
deleted file mode 100644
index 7479c96..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
+++ /dev/null
@@ -1,40 +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.syncpull;
-
-import org.quartz.JobExecutionException;
-
-public interface ProvisioningActions {
-
-    /**
-     * Action to be executed before to start the synchronization task execution.
-     *
-     * @param profile sync profile
-     * @throws JobExecutionException in case of generic failure
-     */
-    void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
-
-    /**
-     * Action to be executed after the synchronization task completion.
-     *
-     * @param profile sync profile
-     * @throws JobExecutionException in case of generic failure
-     */
-    void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
deleted file mode 100644
index 08ab034..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
+++ /dev/null
@@ -1,81 +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.syncpull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.syncope.common.lib.types.ConflictResolutionAction;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-
-public class ProvisioningProfile<T extends ProvisioningTask, A extends ProvisioningActions> {
-
-    /**
-     * Syncing connector.
-     */
-    private final Connector connector;
-
-    private final T task;
-
-    private final List<ProvisioningReport> results = new ArrayList<>();
-
-    private boolean dryRun;
-
-    private ConflictResolutionAction resAct;
-
-    private final List<A> actions = new ArrayList<>();
-
-    public ProvisioningProfile(final Connector connector, final T task) {
-        this.connector = connector;
-        this.task = task;
-    }
-
-    public Connector getConnector() {
-        return connector;
-    }
-
-    public T getTask() {
-        return task;
-    }
-
-    public Collection<ProvisioningReport> getResults() {
-        return results;
-    }
-
-    public boolean isDryRun() {
-        return dryRun;
-    }
-
-    public void setDryRun(final boolean dryRun) {
-        this.dryRun = dryRun;
-    }
-
-    public ConflictResolutionAction getResAct() {
-        return resAct;
-    }
-
-    public void setResAct(final ConflictResolutionAction resAct) {
-        this.resAct = resAct;
-    }
-
-    public List<A> getActions() {
-        return actions;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java
deleted file mode 100644
index 1e82796d..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java
+++ /dev/null
@@ -1,140 +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.syncpull;
-
-import java.util.Collection;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.TraceLevel;
-
-public class ProvisioningReport {
-
-    public enum Status {
-
-        SUCCESS,
-        IGNORE,
-        FAILURE
-
-    }
-
-    private String message;
-
-    private Status status;
-
-    private String anyType;
-
-    private ResourceOperation operation;
-
-    private Long key;
-
-    private String name;
-
-    public String getMessage() {
-        return message;
-    }
-
-    public void setMessage(final String message) {
-        this.message = message;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(final String name) {
-        this.name = name;
-    }
-
-    public Long getKey() {
-        return key;
-    }
-
-    public void setKey(final Long key) {
-        this.key = key;
-    }
-
-    public Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(final Status status) {
-        this.status = status;
-    }
-
-    public String getAnyType() {
-        return anyType;
-    }
-
-    public void setAnyType(final String anyType) {
-        this.anyType = anyType;
-    }
-
-    public ResourceOperation getOperation() {
-        return operation;
-    }
-
-    public void setOperation(final ResourceOperation operation) {
-        this.operation = operation;
-    }
-
-    @Override
-    public String toString() {
-        return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
-    }
-
-    /**
-     * Human readable report string, using the given trace level.
-     *
-     * @param level trace level
-     * @return String for certain levels, null for level NONE
-     */
-    public String getReportString(final TraceLevel level) {
-        if (level == TraceLevel.SUMMARY) {
-            // No per entry log in this case.
-            return null;
-        } else if (level == TraceLevel.FAILURES && status == Status.FAILURE) {
-            // only report failures
-            return String.format("Failed %s (id/name): %d/%s with message: %s", operation, key, name, message);
-        } else {
-            // All
-            return String.format("%s %s (id/name): %d/%s %s", operation, status, key, name,
-                    StringUtils.isBlank(message)
-                            ? ""
-                            : "with message: " + message);
-        }
-    }
-
-    /**
-     * Helper method to invoke logging per synchronization result for the given trace level.
-     *
-     * @param results synchronization result
-     * @param level trace level
-     * @return report as string
-     */
-    public static String produceReport(final Collection<ProvisioningReport> results, final TraceLevel level) {
-        StringBuilder sb = new StringBuilder();
-        for (ProvisioningReport result : results) {
-            sb.append(result.getReportString(level)).append('\n');
-        }
-        return sb.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
deleted file mode 100644
index 75e5a5f..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
+++ /dev/null
@@ -1,163 +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.syncpull;
-
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.quartz.JobExecutionException;
-
-/**
- * Interface for actions to be performed during push.
- * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
- */
-public interface PushActions extends ProvisioningActions {
-
-    /**
-     * Action to be executed before to assign (link &amp; provision) a synchronized any object to the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeAssign(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to provision a synchronized any object to the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeProvision(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to update a synchronized any object on the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be updated.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeUpdate(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to link a synchronized any object to the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeLink(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to unlink a synchronized any object from the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeUnlink(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to unassign a synchronized any object from the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeUnassign(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to unassign a synchronized any object from the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeDeprovision(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before delete a synchronized any object locally and from the resource.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any any object to be created.
-     * @return any.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> A beforeDelete(
-            ProvisioningProfile<?, ?> profile,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed after any object push goes on error.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any synchronized any object.
-     * @param result operation result.
-     * @param error error being reported
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> void onError(
-            ProvisioningProfile<?, ?> profile,
-            A any,
-            ProvisioningReport result,
-            Exception error) throws JobExecutionException;
-
-    /**
-     * Action to be executed after each local any object push.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the push being executed.
-     * @param any synchronized any object.
-     * @param result operation result.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends Any<?>> void after(
-            ProvisioningProfile<?, ?> profile,
-            A any,
-            ProvisioningReport result) throws JobExecutionException;
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java
deleted file mode 100644
index cc073ce..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java
+++ /dev/null
@@ -1,30 +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.syncpull;
-
-import org.identityconnectors.framework.common.objects.filter.Filter;
-
-/**
- * Interface to be implemented for performing filtered reconciliation of a
- * {@link org.apache.syncope.core.persistence.api.entity.task.SyncTask}.
- */
-public interface ReconciliationFilterBuilder {
-
-    Filter build();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
deleted file mode 100644
index ae072b7..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
+++ /dev/null
@@ -1,203 +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.syncpull;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-/**
- * Interface for actions to be performed during synchronization.
- * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the synchronization
- * process.
- */
-public interface SyncActions extends ProvisioningActions {
-
-    /**
-     * Action to be executed before to create a synchronized user / group locally.
-     * User/group is created locally upon synchronization in case of the un-matching rule
-     * {@link org.apache.syncope.common.lib.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeProvision(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before creating (and linking to the resource) a synchronized user / group locally.
-     * User/group is created locally and linked to the synchronized resource upon synchronization in case of the
-     * un-matching rule {@link org.apache.syncope.common.lib.types.UnmatchingRule#ASSIGN} is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeAssign(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before unlinking resource from the synchronized user / group and de-provisioning.
-     * User/group is unlinked and de-provisioned from the synchronized resource upon synchronization in case of the
-     * matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNASSIGN} is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeUnassign(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before de-provisioning action only.
-     * User/group is de-provisioned (without unlinking) from the synchronized resource upon synchronization in case of
-     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#DEPROVISION} is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeDeprovision(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before unlinking resource from the synchronized user / group.
-     * User/group is unlinked (without de-provisioning) from the synchronized resource upon synchronization in case of
-     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNLINK} is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeUnlink(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before linking resource to the synchronized user / group.
-     * User/group is linked (without updating) to the synchronized resource upon synchronization in case of
-     * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#LINK} is applied.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeLink(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed before to update a synchronized user / group locally.
-     * User/group is updated upon synchronization in case of the matching rule
-     * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
-     *
-     * @param <M> concrete any object
-     * @param <P> any object modifications
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object
-     * @param anyPatch modification
-     * @return synchronization information used for logging and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure.
-     */
-    <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            M any,
-            P anyPatch)
-            throws JobExecutionException;
-
-    /**
-     * Action to be executed before to delete a synchronized user / group locally.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information
-     * @param any any object to be deleted
-     * @return synchronization information used for logging and to be passed to the 'after' method.
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> SyncDelta beforeDelete(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any) throws JobExecutionException;
-
-    /**
-     * Action to be executed when user / group synchronization goes on error.
-     *
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information (may be modified by
-     * 'beforeProvision/beforeUpdate/beforeDelete')
-     * @param result global synchronization results at the current synchronization step
-     * @param error error being reported
-     * @throws JobExecutionException in case of generic failure
-     */
-    void onError(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            ProvisioningReport result,
-            Exception error) throws JobExecutionException;
-
-    /**
-     * Action to be executed after each local user / group synchronization.
-     *
-     * @param <A> concrete any object
-     * @param profile profile of the synchronization being executed.
-     * @param delta retrieved synchronization information (may be modified by beforeProvision / beforeUpdate /
-     * beforeDelete)
-     * @param any any object
-     * @param result global synchronization results at the current synchronization step
-     * @throws JobExecutionException in case of generic failure
-     */
-    <A extends AnyTO> void after(
-            ProvisioningProfile<?, ?> profile,
-            SyncDelta delta,
-            A any,
-            ProvisioningReport result) throws JobExecutionException;
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
deleted file mode 100644
index dff841a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
+++ /dev/null
@@ -1,36 +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.syncpull;
-
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-
-/**
- * Interface for correlation rule to be evaluated during SyncJob execution.
- */
-public interface SyncCorrelationRule {
-
-    /**
-     * Return a search condition.
-     *
-     * @param connObj connector object.
-     * @return search condition.
-     */
-    SearchCond getSearchCond(ConnectorObject connObj);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java
deleted file mode 100644
index deb6e9b..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.syncpull;
-
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-
-public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
-
-    boolean handle(long anyKey);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java
deleted file mode 100644
index c078ef2..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java
+++ /dev/null
@@ -1,29 +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.syncpull;
-
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-
-public interface SyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions> {
-
-    ProvisioningProfile<T, A> getProfile();
-
-    void setProfile(ProvisioningProfile<T, A> profile);
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java
deleted file mode 100644
index 5c293830..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java
+++ /dev/null
@@ -1,29 +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.syncpull;
-
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-
-public interface SyncopeSyncResultHandler extends SyncopeResultHandler<SyncTask, SyncActions>, SyncResultsHandler {
-
-    @Override
-    boolean handle(SyncDelta delta);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
deleted file mode 100644
index 8a0459a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.syncpull;
-
-public interface UserPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
deleted file mode 100644
index 7f9c827..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
+++ /dev/null
@@ -1,23 +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.syncpull;
-
-public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/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 4e7f9e9..438d97f 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
@@ -38,7 +38,7 @@ import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
 import org.identityconnectors.common.security.GuardedByteArray;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.APIConfiguration;

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/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 cd3fc5c..8abf123 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
@@ -49,7 +49,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -150,11 +150,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         try {
             updated = uwfAdapter.update(userPatch);
         } catch (Exception e) {
-            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)",
+            LOG.error("Update of user {} failed, trying to pull its status anyway (if configured)",
                     userPatch.getKey(), e);
 
             result.setStatus(ProvisioningReport.Status.FAILURE);
-            result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
+            result.setMessage("Update failed, trying to pull status anyway (if configured)\n" + e.getMessage());
 
             updated = new WorkflowResult<Pair<UserPatch, Boolean>>(
                     new ImmutablePair<>(userPatch, false), new PropagationByResource(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index 7c97448..a5cd9d6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -151,7 +151,7 @@ public class MappingManagerImpl implements MappingManager {
         List<MappingItem> result = new ArrayList<>();
 
         switch (purpose) {
-            case SYNCHRONIZATION:
+            case PULL:
                 for (MappingItem item : items) {
                     if (MappingPurpose.PROPAGATION != item.getPurpose()
                             && MappingPurpose.NONE != item.getPurpose()) {
@@ -163,7 +163,7 @@ public class MappingManagerImpl implements MappingManager {
 
             case PROPAGATION:
                 for (MappingItem item : items) {
-                    if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
+                    if (MappingPurpose.PULL != item.getPurpose()
                             && MappingPurpose.NONE != item.getPurpose()) {
 
                         result.add(item);
@@ -201,8 +201,8 @@ public class MappingManagerImpl implements MappingManager {
         return getMappingItems(provision, MappingPurpose.PROPAGATION);
     }
 
-    public static List<MappingItem> getSyncMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.SYNCHRONIZATION);
+    public static List<MappingItem> getPullMappingItems(final Provision provision) {
+        return getMappingItems(provision, MappingPurpose.PULL);
     }
 
     /**
@@ -728,7 +728,7 @@ public class MappingManagerImpl implements MappingManager {
         if (attr != null) {
             values = attr.getValue();
             for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
-                values = transformer.beforeSync(values);
+                values = transformer.beforePull(values);
             }
         }
         values = ListUtils.emptyIfNull(values);

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
index 3810a87..70cd1d0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
@@ -33,7 +33,7 @@ public class DefaultMappingItemTransformer implements MappingItemTransformer {
     }
 
     @Override
-    public List<Object> beforeSync(final List<Object> values) {
+    public List<Object> beforePull(final List<Object> values) {
         return values;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index f2074f8..92149c3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -27,7 +27,7 @@ import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
@@ -37,11 +37,11 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 @Component
 public class PolicyDataBinderImpl implements PolicyDataBinder {
@@ -92,10 +92,10 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
                 accountPolicyTO.getResources().addAll(accountPolicy.getResourceNames());
                 break;
 
-            case SYNC:
+            case PULL:
             default:
-                policyTO = (T) new SyncPolicyTO();
-                ((SyncPolicyTO) policyTO).setSpecification(((SyncPolicy) policy).getSpecification());
+                policyTO = (T) new PullPolicyTO();
+                ((PullPolicyTO) policyTO).setSpecification(((PullPolicy) policy).getSpecification());
         }
 
         policyTO.setKey(policy.getKey());
@@ -172,16 +172,16 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
                 }
                 break;
 
-            case SYNC:
+            case PULL:
             default:
-                if (!(policyTO instanceof SyncPolicyTO)) {
-                    throw new ClassCastException("Expected " + SyncPolicyTO.class.getName()
+                if (!(policyTO instanceof PullPolicyTO)) {
+                    throw new ClassCastException("Expected " + PullPolicyTO.class.getName()
                             + ", found " + policyTO.getClass().getName());
                 }
                 if (result == null) {
-                    result = (T) entityFactory.newEntity(SyncPolicy.class);
+                    result = (T) entityFactory.newEntity(PullPolicy.class);
                 }
-                ((SyncPolicy) result).setSpecification(((SyncPolicyTO) policyTO).getSpecification());
+                ((PullPolicy) result).setSpecification(((PullPolicyTO) policyTO).getSpecification());
         }
 
         result.setDescription(policyTO.getDescription());


[12/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
index 1925785..a50f801 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.html
@@ -23,9 +23,9 @@ under the License.
       <div class="form-group"><span wicket:id="name">[id]</span></div>
       <div class="form-group"><span wicket:id="description">[anyKey]</span></div>
       <div class="form-group"><span wicket:id="active">[active]</span></div>
-      <span wicket:id="syncTaskSpecifics">
+      <span wicket:id="pullTaskSpecifics">
         <div class="form-group"><span wicket:id="destinationRealm">[destinationRealm]</span></div>
-        <div class="form-group"><span wicket:id="syncMode">[syncMode]</span></div>
+        <div class="form-group"><span wicket:id="pullMode">[pullMode]</span></div>
         <div class="form-group"><span wicket:id="reconciliationFilterBuilderClassName">[filter]</span></div>
       </span>
       <div class="form-group"><span wicket:id="jobDelegateClassName">[jobDelegateClassName]</span></div>
@@ -36,7 +36,7 @@ under the License.
         <div class="form-group"><span wicket:id="performCreate">[performCreate]</span></div>
         <div class="form-group"><span wicket:id="performUpdate">[performUpdate]</span></div>
         <div class="form-group"><span wicket:id="performDelete">[performDelete]</span></div>
-        <div class="form-group"><span wicket:id="syncStatus">[syncStatus]</span></div>
+        <div class="form-group"><span wicket:id="pullStatus">[pullStatus]</span></div>
       </span>
 
       <div class="form-group"><span wicket:id="lastExec">[lastExec]</span></div>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.properties
index 10c27ec..91d6e03 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile.properties
@@ -19,10 +19,10 @@ description=Description
 jobDelegateClassName=Class
 matchingRule=Matching rule
 unmatchingRule=Unmatching rule
-performCreate=Synchronize created objects
-performUpdate=Synchronize updated objects
-performDelete=Synchronize deleted objects
-syncStatus=Synchronize status
+performCreate=Create pulled objects
+performUpdate=Update pulled objects
+performDelete=Delete pulled objects
+pullStatus=Pull status
 lastExec=Last Execution
 nextExec=Next Execution
 detail=Detail

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_it.properties
index 62edea3..a0f3cd4 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_it.properties
@@ -19,10 +19,10 @@ description=Description
 jobDelegateClassName=Class
 matchingRule=Regola di matching
 unmatchingRule=Regola di unmatching
-performCreate=Sincronizza oggetti creati
-performUpdate=Sincronizza oggetti modificati
-performDelete=Sincronizza oggetti rimossi
-syncStatus=Sincronizza stato
+performCreate=Crea oggetti da pull
+performUpdate=Aggiorna oggetti da pull
+performDelete=Rimuovi oggetti da pull
+pullStatus=Recupera stato
 lastExec=Last Execution
 nextExec=Next Execution
 detail=Detail

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_pt_BR.properties
index 5e07a6b..91d6e03 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder$Profile_pt_BR.properties
@@ -16,13 +16,13 @@
 # under the License.
 name=Name
 description=Description
-jobDelegateClassName=ClassmatchingRule=Matching rule
+jobDelegateClassName=Class
 matchingRule=Matching rule
 unmatchingRule=Unmatching rule
-performCreate=Synchronize created objects
-performUpdate=Synchronize updated objects
-performDelete=Synchronize deleted objects
-syncStatus=Synchronize status
+performCreate=Create pulled objects
+performUpdate=Update pulled objects
+performDelete=Delete pulled objects
+pullStatus=Pull status
 lastExec=Last Execution
 nextExec=Next Execution
 detail=Detail

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
index 5cd694b..20f7260 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
@@ -37,7 +37,7 @@ under the License.
           <li><i class="fa fa-minus"></i><a href="#" wicket:id="delete"><wicket:message key="resource.menu.remove"/></a></li>
           <li><i class="fa fa-pencil"></i><a href="#" wicket:id="edit"><wicket:message key="resource.menu.edit"/></a></li>
           <li><i class="fa fa-arrow-right"></i><a href="#" wicket:id="propagation"><wicket:message key="task.propagation.list"/></a></li>
-          <li><i class="fa fa-chevron-circle-left"></i><a href="#" wicket:id="synchronization"><wicket:message key="task.synchronization.list"/></a></li>
+          <li><i class="fa fa-chevron-circle-left"></i><a href="#" wicket:id="pull"><wicket:message key="task.pull.list"/></a></li>
           <li><i class="fa fa-chevron-circle-right"></i><a href="#" wicket:id="push"><wicket:message key="task.push.list"/></a></li>
         </ul>
       </wicket:fragment>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
index 3dd4ed8..2db9d85 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.properties
@@ -28,5 +28,5 @@ resource.menu.edit=Edit resource
 
 task.generic.list=Generic tasks
 task.propagation.list=Propagation tasks
-task.synchronization.list=Synchronization tasks
+task.pull.list=Pull tasks
 task.push.list=Push tasks

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
index 6641a6f..82f95e8 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_it.properties
@@ -28,5 +28,5 @@ resource.menu.edit=Modifica risorsa
 
 task.generic.list=Task generici
 task.propagation.list=Task di propagazione
-task.synchronization.list=Task di sincronizzazione
+task.pull.list=Pull task
 task.push.list=Push task

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
index 06d3608..2c987e5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel_pt_BR.properties
@@ -28,5 +28,5 @@ resource.menu.edit=Alterar recurso
 
 task.generic.list=Generic tasks
 task.propagation.list=Propagation tasks
-task.synchronization.list=Synchronization tasks
+task.pull.list=Pull tasks
 task.push.list=Push tasks

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
index f14e105..46be9d4 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.html
@@ -21,7 +21,7 @@ under the License.
 
     <a href="#" wicket:id="propagationPurposeLink"><i class="fa fa-arrow-circle-o-right"></i></a>
 
-    <a href="#" wicket:id="synchronizationPurposeLink"><i class="fa fa-arrow-circle-o-left"></i></a>
+    <a href="#" wicket:id="pullPurposeLink"><i class="fa fa-arrow-circle-o-left"></i></a>
 
     <a href="#" wicket:id="bothPurposeLink"><i class="fa fa-exchange"></i></a>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
index 2e48d08..f2ceabc 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
@@ -27,7 +27,7 @@ under the License.
               <i class="fa fa-wrench"></i>
             </button>
             <ul class="dropdown-menu" role="menu">
-              <li><a href="#" wicket:id="topology"><wicket:message key="createResourceOrSyncTask"/></a></li>
+              <li><a href="#" wicket:id="topology"><wicket:message key="createResourceOrPullTask"/></a></li>
               <li><a href="#" wicket:id="policies"><wicket:message key="createPolicy"/></a></li>
               <li><a href="#" wicket:id="notifications"><wicket:message key="createNotification"/></a></li>
               <li><a href="#" wicket:id="types"><wicket:message key="createVirSchemaOrAnyType"/></a></li>

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
index e40cc59..1693f61 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 configurationStatus=Configuration Status
-createResourceOrSyncTask=Create Resource or SyncTask
+createResourceOrPullTask=Create Resource or PullTask
 createPolicy=Create Policy
 createVirSchemaOrAnyType=Create Virtual Schema or AnyType
 createSecurityQuestion=Create Security Question

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
index 641d93e..37252bf 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 configurationStatus=Stato Configurazione
-createResourceOrSyncTask=Crea Risorsa o SyncTask
+createResourceOrPullTask=Crea Risorsa o PullTask
 createPolicy=Crea Politica
 createVirSchemaOrAnyType=Crea Virtual Schema o AnyType
 createSecurityQuestion=Crea Domanda di Sicurezza

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
index d921be0..774a9d9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 configurationStatus=Estado de configura\u00e7\u00e3o
-createResourceOrSyncTask=Criar recursos ou SyncTask
+createResourceOrPullTask=Criar recursos ou PullTask
 createPolicy=Criar Politica
 createVirSchemaOrAnyType=Criar Virtual Schema ou AnyType
 createSecurityQuestion=Criar Perguntas de Seguran\u00e7a 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
index 790ec59..ec8d20f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
@@ -77,11 +77,11 @@ public class PlatformInfo extends AbstractBaseBean {
 
     private final Set<String> propagationActions = new HashSet<>();
 
-    private final Set<String> syncActions = new HashSet<>();
+    private final Set<String> pullActions = new HashSet<>();
 
     private final Set<String> pushActions = new HashSet<>();
 
-    private final Set<String> syncCorrelationRules = new HashSet<>();
+    private final Set<String> pullCorrelationRules = new HashSet<>();
 
     private final Set<String> pushCorrelationRules = new HashSet<>();
 
@@ -211,11 +211,11 @@ public class PlatformInfo extends AbstractBaseBean {
         return propagationActions;
     }
 
-    @XmlElementWrapper(name = "syncActions")
-    @XmlElement(name = "syncAction")
-    @JsonProperty("syncActions")
-    public Set<String> getSyncActions() {
-        return syncActions;
+    @XmlElementWrapper(name = "pullActions")
+    @XmlElement(name = "pullAction")
+    @JsonProperty("pullActions")
+    public Set<String> getPullActions() {
+        return pullActions;
     }
 
     @XmlElementWrapper(name = "pushActions")
@@ -225,11 +225,11 @@ public class PlatformInfo extends AbstractBaseBean {
         return pushActions;
     }
 
-    @XmlElementWrapper(name = "syncCorrelationRules")
-    @XmlElement(name = "syncCorrelationRule")
-    @JsonProperty("syncCorrelationRules")
-    public Set<String> getSyncCorrelationRules() {
-        return syncCorrelationRules;
+    @XmlElementWrapper(name = "pullCorrelationRules")
+    @XmlElement(name = "pullCorrelationRule")
+    @JsonProperty("pullCorrelationRules")
+    public Set<String> getPullCorrelationRules() {
+        return pullCorrelationRules;
     }
 
     @XmlElementWrapper(name = "pushCorrelationRules")

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
index 9157ba2..34f824f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
@@ -33,7 +33,7 @@ import org.apache.syncope.common.lib.types.PolicyType;
 
 @XmlRootElement(name = "abstractPolicy")
 @XmlType
-@XmlSeeAlso({ AccountPolicyTO.class, PasswordPolicyTO.class, SyncPolicyTO.class })
+@XmlSeeAlso({ AccountPolicyTO.class, PasswordPolicyTO.class, PullPolicyTO.class })
 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
 public abstract class AbstractPolicyTO extends AbstractBaseBean {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyType.java
index 7f1c11e..ea429c2 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyType.java
@@ -32,9 +32,9 @@ public enum PolicyType {
      */
     PASSWORD,
     /**
-     * For handling conflicts resolution during synchronization.
+     * For handling conflicts resolution during pull.
      */
-    SYNC,
+    PULL,
     /**
      * For handling conflicts resolution during push.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicySpec.java
new file mode 100644
index 0000000..a6b5338
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicySpec.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.policy;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
+import org.apache.syncope.common.lib.types.ConflictResolutionAction;
+
+@XmlType
+public class PullPolicySpec extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -3144027171719498127L;
+
+    private ConflictResolutionAction conflictResolutionAction;
+
+    /**
+     * Associates anyTypeKey to either:
+     * <ol>
+     * <li>Java class name, implementing {@code PullCorrelationRule}</li>
+     * <li>JSON array containing plain schema names - this will be used to feed
+     * {@code PlainAttrsPullCorrelationRule}</li>
+     * </ol>
+     */
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
+    private final Map<String, String> correlationRules = new HashMap<>();
+
+    public ConflictResolutionAction getConflictResolutionAction() {
+        return conflictResolutionAction == null
+                ? ConflictResolutionAction.IGNORE
+                : conflictResolutionAction;
+    }
+
+    public void setConflictResolutionAction(final ConflictResolutionAction conflictResolutionAction) {
+        this.conflictResolutionAction = conflictResolutionAction;
+    }
+
+    @JsonProperty
+    public Map<String, String> getCorrelationRules() {
+        return correlationRules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
new file mode 100644
index 0000000..91c8e8b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.policy;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.types.PolicyType;
+
+@XmlRootElement(name = "pullPolicy")
+@XmlType
+public class PullPolicyTO extends AbstractPolicyTO {
+
+    private static final long serialVersionUID = 993024634238024242L;
+
+    private PullPolicySpec specification;
+
+    public PullPolicyTO() {
+        super(PolicyType.PULL);
+    }
+
+    public PullPolicySpec getSpecification() {
+        return specification;
+    }
+
+    public void setSpecification(final PullPolicySpec specification) {
+        this.specification = specification;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
deleted file mode 100644
index 2a31d64..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicySpec.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.policy;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.HashMap;
-import java.util.Map;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
-import org.apache.syncope.common.lib.types.ConflictResolutionAction;
-
-@XmlType
-public class SyncPolicySpec extends AbstractBaseBean {
-
-    private static final long serialVersionUID = -3144027171719498127L;
-
-    private ConflictResolutionAction conflictResolutionAction;
-
-    /**
-     * Associates anyTypeKey to either:
-     * <ol>
-     * <li>Java class name, implementing {@code SyncCorrelationRule}</li>
-     * <li>JSON array containing plain schema names - this will be used to feed
-     * {@code PlainAttrsSyncCorrelationRule}</li>
-     * </ol>
-     */
-    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
-    @JsonIgnore
-    private final Map<String, String> correlationRules = new HashMap<>();
-
-    public ConflictResolutionAction getConflictResolutionAction() {
-        return conflictResolutionAction == null
-                ? ConflictResolutionAction.IGNORE
-                : conflictResolutionAction;
-    }
-
-    public void setConflictResolutionAction(final ConflictResolutionAction conflictResolutionAction) {
-        this.conflictResolutionAction = conflictResolutionAction;
-    }
-
-    @JsonProperty
-    public Map<String, String> getCorrelationRules() {
-        return correlationRules;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicyTO.java
deleted file mode 100644
index 911c445..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/SyncPolicyTO.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.policy;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.types.PolicyType;
-
-@XmlRootElement(name = "syncPolicy")
-@XmlType
-public class SyncPolicyTO extends AbstractPolicyTO {
-
-    private static final long serialVersionUID = 993024634238024242L;
-
-    private SyncPolicySpec specification;
-
-    public SyncPolicyTO() {
-        super(PolicyType.SYNC);
-    }
-
-    public SyncPolicySpec getSpecification() {
-        return specification;
-    }
-
-    public void setSpecification(final SyncPolicySpec specification) {
-        this.specification = specification;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
index cd63bcd..ae6094b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.types.UnmatchingRule;
 
 @XmlRootElement(name = "abstractProvisioningTask")
 @XmlType
-@XmlSeeAlso({ PushTaskTO.class, SyncTaskTO.class })
+@XmlSeeAlso({ PushTaskTO.class, PullTaskTO.class })
 public class AbstractProvisioningTaskTO extends SchedTaskTO {
 
     private static final long serialVersionUID = -2143537546915809016L;
@@ -84,11 +84,11 @@ public class AbstractProvisioningTaskTO extends SchedTaskTO {
         this.performDelete = performDelete;
     }
 
-    public boolean isSyncStatus() {
+    public boolean isPullStatus() {
         return syncStatus;
     }
 
-    public void setSyncStatus(final boolean syncStatus) {
+    public void setPullStatus(final boolean syncStatus) {
         this.syncStatus = syncStatus;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
new file mode 100644
index 0000000..6063c4d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
+import org.apache.syncope.common.lib.types.PullMode;
+
+@XmlRootElement(name = "pullTask")
+@XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PullTaskTO extends AbstractProvisioningTaskTO {
+
+    private static final long serialVersionUID = -2143537546915809017L;
+
+    private PullMode pullMode;
+
+    private String reconciliationFilterBuilderClassName;
+
+    private String destinationRealm;
+
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
+    private final Map<String, AnyTO> templates = new HashMap<>();
+
+    public PullMode getPullMode() {
+        return pullMode;
+    }
+
+    public void setPullMode(final PullMode pullMode) {
+        this.pullMode = pullMode;
+    }
+
+    public String getReconciliationFilterBuilderClassName() {
+        return reconciliationFilterBuilderClassName;
+    }
+
+    public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) {
+        this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName;
+    }
+
+    public String getDestinationRealm() {
+        return destinationRealm;
+    }
+
+    public void setDestinationRealm(final String destinationRealm) {
+        this.destinationRealm = destinationRealm;
+    }
+
+    @JsonProperty
+    public Map<String, AnyTO> getTemplates() {
+        return templates;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index 5f75794..0f176c4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -68,13 +68,13 @@ public class ResourceTO extends AbstractAnnotatedBean implements EntityTO<String
 
     private TraceLevel deleteTraceLevel = TraceLevel.ALL;
 
-    private TraceLevel syncTraceLevel = TraceLevel.ALL;
+    private TraceLevel pullTraceLevel = TraceLevel.ALL;
 
     private Long passwordPolicy;
 
     private Long accountPolicy;
 
-    private Long syncPolicy;
+    private Long pullPolicy;
 
     private final Set<ConnConfProperty> confOverride = new HashSet<>();
 
@@ -175,12 +175,12 @@ public class ResourceTO extends AbstractAnnotatedBean implements EntityTO<String
         this.accountPolicy = accountPolicy;
     }
 
-    public Long getSyncPolicy() {
-        return syncPolicy;
+    public Long getPullPolicy() {
+        return pullPolicy;
     }
 
-    public void setSyncPolicy(final Long syncPolicy) {
-        this.syncPolicy = syncPolicy;
+    public void setPullPolicy(final Long pullPolicy) {
+        this.pullPolicy = pullPolicy;
     }
 
     @JsonIgnore
@@ -223,12 +223,12 @@ public class ResourceTO extends AbstractAnnotatedBean implements EntityTO<String
         return capabilitiesOverride;
     }
 
-    public TraceLevel getSyncTraceLevel() {
-        return syncTraceLevel;
+    public TraceLevel getPullTraceLevel() {
+        return pullTraceLevel;
     }
 
-    public void setSyncTraceLevel(final TraceLevel syncTraceLevel) {
-        this.syncTraceLevel = syncTraceLevel;
+    public void setPullTraceLevel(final TraceLevel pullTraceLevel) {
+        this.pullTraceLevel = pullTraceLevel;
     }
 
     @XmlElementWrapper(name = "propagationActionsClassNames")

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
deleted file mode 100644
index 312f654..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.HashMap;
-import java.util.Map;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
-import org.apache.syncope.common.lib.types.SyncMode;
-
-@XmlRootElement(name = "syncTask")
-@XmlType
-@XmlAccessorType(XmlAccessType.FIELD)
-public class SyncTaskTO extends AbstractProvisioningTaskTO {
-
-    private static final long serialVersionUID = -2143537546915809017L;
-
-    private SyncMode syncMode;
-
-    private String reconciliationFilterBuilderClassName;
-
-    private String destinationRealm;
-
-    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
-    @JsonIgnore
-    private final Map<String, AnyTO> templates = new HashMap<>();
-
-    public SyncMode getSyncMode() {
-        return syncMode;
-    }
-
-    public void setSyncMode(final SyncMode syncMode) {
-        this.syncMode = syncMode;
-    }
-
-    public String getReconciliationFilterBuilderClassName() {
-        return reconciliationFilterBuilderClassName;
-    }
-
-    public void setReconciliationFilterBuilderClassName(final String reconciliationFilterBuilderClassName) {
-        this.reconciliationFilterBuilderClassName = reconciliationFilterBuilderClassName;
-    }
-
-    public String getDestinationRealm() {
-        return destinationRealm;
-    }
-
-    public void setDestinationRealm(final String destinationRealm) {
-        this.destinationRealm = destinationRealm;
-    }
-
-    @JsonProperty
-    public Map<String, AnyTO> getTemplates() {
-        return templates;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
index c3d4af5..bf45a42 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
@@ -36,7 +36,7 @@ public final class AuditElements implements Serializable {
         REST(StringUtils.EMPTY),
         TASK(StringUtils.EMPTY),
         PROPAGATION("PropagationTask"),
-        SYNCHRONIZATION("SyncTask"),
+        PULL("PullTask"),
         PUSH("PushTask"),
         CUSTOM(StringUtils.EMPTY);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
index fe9770a..5e89dcf 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java
@@ -127,8 +127,8 @@ public class AuditLoggerName extends AbstractBaseBean {
 
                 if (EventCategoryType.PROPAGATION.toString().equals(elements[0])) {
                     type = EventCategoryType.PROPAGATION;
-                } else if (EventCategoryType.SYNCHRONIZATION.toString().equals(elements[0])) {
-                    type = EventCategoryType.SYNCHRONIZATION;
+                } else if (EventCategoryType.PULL.toString().equals(elements[0])) {
+                    type = EventCategoryType.PULL;
                 } else if (EventCategoryType.PUSH.toString().equals(elements[0])) {
                     type = EventCategoryType.PUSH;
                 } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 0fc8a7f..bceff27 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -61,7 +61,7 @@ public enum ClientExceptionType {
     InvalidNotification(Response.Status.BAD_REQUEST),
     InvalidPropagationTask(Response.Status.BAD_REQUEST),
     InvalidSchedTask(Response.Status.BAD_REQUEST),
-    InvalidSyncTask(Response.Status.BAD_REQUEST),
+    InvalidPullTask(Response.Status.BAD_REQUEST),
     InvalidValues(Response.Status.BAD_REQUEST),
     NotFound(Response.Status.NOT_FOUND),
     RejectedUserCreate(Response.Status.BAD_REQUEST),

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
index 4b7cc38..7532730 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
@@ -42,7 +42,7 @@ public enum EntityViolationType {
     InvalidSchemaEnum("org.apache.syncope.core.persistence.validation.schema.enum"),
     InvalidSchemaMultivalueUnique("org.apache.syncope.core.persistence.validation.schema.multivalueUnique"),
     InvalidSchedTask("org.apache.syncope.core.persistence.validation.schedtask"),
-    InvalidProvisioningTask("org.apache.syncope.core.persistence.validation.synctask"),
+    InvalidProvisioningTask("org.apache.syncope.core.persistence.validation.provisioningtask"),
     InvalidPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.plainSchema"),
     InvalidDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.derSchema"),
     InvalidVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.virSchema"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/MappingPurpose.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/MappingPurpose.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/MappingPurpose.java
index dc8c23e..59ee9b3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/MappingPurpose.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/MappingPurpose.java
@@ -21,7 +21,7 @@ package org.apache.syncope.common.lib.types;
 public enum MappingPurpose {
 
     BOTH,
-    SYNCHRONIZATION,
+    PULL,
     PROPAGATION,
     NONE
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/PullMode.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PullMode.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PullMode.java
new file mode 100644
index 0000000..522c30d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PullMode.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum PullMode {
+    FULL_RECONCILIATION,
+    FILTERED_RECONCILIATION,
+    INCREMENTAL;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java
deleted file mode 100644
index afa9f19..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum SyncMode {
-    FULL_RECONCILIATION,
-    FILTERED_RECONCILIATION,
-    INCREMENTAL;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/common/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
index d17ecc7..fcebb1c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/TaskType.java
@@ -26,7 +26,7 @@ public enum TaskType {
     PROPAGATION,
     NOTIFICATION,
     SCHEDULED,
-    SYNCHRONIZATION,
+    PULL,
     PUSH;
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index adb33d0..4ecd0a1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -57,8 +57,8 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.spring.BeanUtils;
-import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -294,13 +294,13 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             events.add(authenticationControllerEvents);
 
             events.add(new EventCategoryTO(EventCategoryType.PROPAGATION));
-            events.add(new EventCategoryTO(EventCategoryType.SYNCHRONIZATION));
+            events.add(new EventCategoryTO(EventCategoryType.PULL));
             events.add(new EventCategoryTO(EventCategoryType.PUSH));
 
             for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
                 for (ExternalResource resource : resourceDAO.findAll()) {
                     EventCategoryTO propEventCategoryTO = new EventCategoryTO(EventCategoryType.PROPAGATION);
-                    EventCategoryTO syncEventCategoryTO = new EventCategoryTO(EventCategoryType.SYNCHRONIZATION);
+                    EventCategoryTO syncEventCategoryTO = new EventCategoryTO(EventCategoryType.PULL);
                     EventCategoryTO pushEventCategoryTO = new EventCategoryTO(EventCategoryType.PUSH);
 
                     propEventCategoryTO.setCategory(anyTypeKind.name().toLowerCase());
@@ -342,7 +342,7 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             }
 
             EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
-            eventCategoryTO.setCategory(SyncJobDelegate.class.getSimpleName());
+            eventCategoryTO.setCategory(PullJobDelegate.class.getSimpleName());
             events.add(eventCategoryTO);
 
             eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
index 8f8baa5..76c0d66 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
@@ -27,7 +27,7 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -35,11 +35,11 @@ import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
 @Component
 public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
@@ -82,10 +82,10 @@ public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.POLICY_UPDATE + "')")
-    public SyncPolicyTO update(final SyncPolicyTO policyTO) {
+    public PullPolicyTO update(final PullPolicyTO policyTO) {
         Policy policy = policyDAO.find(policyTO.getKey());
-        if (!(policy instanceof SyncPolicy)) {
-            throw new NotFoundException("SyncPolicy with key " + policyTO.getKey());
+        if (!(policy instanceof PullPolicy)) {
+            throw new NotFoundException(PullPolicy.class.getSimpleName() + " with key " + policyTO.getKey());
         }
 
         return update(policyTO, policy);

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 5f2e632..af8d1e1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -185,9 +185,9 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
                         addAll(implLookup.getClassNames(Type.RECONCILIATION_FILTER_BUILDER));
                 PLATFORM_INFO.getLogicActions().addAll(implLookup.getClassNames(Type.LOGIC_ACTIONS));
                 PLATFORM_INFO.getPropagationActions().addAll(implLookup.getClassNames(Type.PROPAGATION_ACTIONS));
-                PLATFORM_INFO.getSyncActions().addAll(implLookup.getClassNames(Type.SYNC_ACTIONS));
+                PLATFORM_INFO.getPullActions().addAll(implLookup.getClassNames(Type.SYNC_ACTIONS));
                 PLATFORM_INFO.getPushActions().addAll(implLookup.getClassNames(Type.PUSH_ACTIONS));
-                PLATFORM_INFO.getSyncCorrelationRules().addAll(implLookup.getClassNames(Type.SYNC_CORRELATION_RULE));
+                PLATFORM_INFO.getPullCorrelationRules().addAll(implLookup.getClassNames(Type.PULL_CORRELATION_RULE));
                 PLATFORM_INFO.getValidators().addAll(implLookup.getClassNames(Type.VALIDATOR));
                 PLATFORM_INFO.getNotificationRecipientsProviders().
                         addAll(implLookup.getClassNames(Type.NOTIFICATION_RECIPIENTS_PROVIDER));
@@ -285,7 +285,7 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
         numbersInfo.getConfCompleteness().put(
                 NumbersInfo.ConfItem.NOTIFICATION, !notificationDAO.findAll().isEmpty());
         numbersInfo.getConfCompleteness().put(
-                NumbersInfo.ConfItem.SYNC_TASK, !taskDAO.findAll(TaskType.SYNCHRONIZATION).isEmpty());
+                NumbersInfo.ConfItem.SYNC_TASK, !taskDAO.findAll(TaskType.PULL).isEmpty());
         numbersInfo.getConfCompleteness().put(
                 NumbersInfo.ConfItem.VIR_SCHEMA, !virSchemaDAO.findAll().isEmpty());
         numbersInfo.getConfCompleteness().put(

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 0bb270d..a9ec0a5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -197,7 +197,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
                 break;
 
             case SCHEDULED:
-            case SYNCHRONIZATION:
+            case PULL:
             case PUSH:
                 if (!((SchedTask) task).isActive()) {
                     SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling);
@@ -252,7 +252,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
         T taskToDelete = binder.getTaskTO(task, taskUtils, true);
 
         if (TaskType.SCHEDULED == taskUtils.getType()
-                || TaskType.SYNCHRONIZATION == taskUtils.getType()
+                || TaskType.PULL == taskUtils.getType()
                 || TaskType.PUSH == taskUtils.getType()) {
 
             jobManager.unregister(task);

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index 200fd13..7dbf516 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -42,11 +42,9 @@ import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
-import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
-import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -54,7 +52,9 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen
 import org.springframework.core.type.filter.AssignableTypeFilter;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ClassUtils;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 
 /**
  * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
@@ -98,9 +98,9 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
         scanner.addIncludeFilter(new AssignableTypeFilter(ReconciliationFilterBuilder.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PropagationActions.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(PullActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(SyncCorrelationRule.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(PullCorrelationRule.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(Validator.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(NotificationRecipientsProvider.class));
 
@@ -140,7 +140,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                 }
 
                 if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbsractClazz
-                        && !SyncJobDelegate.class.isAssignableFrom(clazz)
+                        && !PullJobDelegate.class.isAssignableFrom(clazz)
                         && !PushJobDelegate.class.isAssignableFrom(clazz)) {
 
                     classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
@@ -158,7 +158,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                     classNames.get(Type.PROPAGATION_ACTIONS).add(bd.getBeanClassName());
                 }
 
-                if (SyncActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+                if (PullActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
                     classNames.get(Type.SYNC_ACTIONS).add(bd.getBeanClassName());
                 }
 
@@ -166,8 +166,8 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                     classNames.get(Type.PUSH_ACTIONS).add(bd.getBeanClassName());
                 }
 
-                if (SyncCorrelationRule.class.isAssignableFrom(clazz) && !isAbsractClazz) {
-                    classNames.get(Type.SYNC_CORRELATION_RULE).add(bd.getBeanClassName());
+                if (PullCorrelationRule.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+                    classNames.get(Type.PULL_CORRELATION_RULE).add(bd.getBeanClassName());
                 }
 
                 if (Validator.class.isAssignableFrom(clazz) && !isAbsractClazz) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
index 2fa7b32..dec65f5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
@@ -42,7 +42,6 @@ import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.logic.notification.NotificationJob;
@@ -52,8 +51,8 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.provisioning.java.job.TaskJob;
-import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.quartz.CronScheduleBuilder;
 import org.quartz.Job;
 import org.quartz.JobBuilder;
@@ -76,6 +75,7 @@ import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.identityconnectors.common.IOUtil;
 import org.quartz.impl.jdbcjobstore.Constants;
 import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 
 @Component
 public class JobManagerImpl implements JobManager, SyncopeLoader {
@@ -229,8 +229,8 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
         TaskJob job = createSpringBean(TaskJob.class);
         job.setTaskKey(task.getKey());
 
-        String jobDelegateClassName = task instanceof SyncTask
-                ? SyncJobDelegate.class.getName()
+        String jobDelegateClassName = task instanceof PullTask
+                ? PullJobDelegate.class.getName()
                 : task instanceof PushTask
                         ? PushJobDelegate.class.getName()
                         : task.getJobDelegateClassName();
@@ -321,7 +321,7 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
                 public Void exec() {
                     // 1. jobs for SchedTasks
                     Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
-                    tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
+                    tasks.addAll(taskDAO.<PullTask>findAll(TaskType.PULL));
                     tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
                     for (SchedTask task : tasks) {
                         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
index ff7284a..6a88085 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
@@ -40,7 +40,7 @@ public interface ImplementationLookup extends SyncopeLoader {
         PROPAGATION_ACTIONS,
         SYNC_ACTIONS,
         PUSH_ACTIONS,
-        SYNC_CORRELATION_RULE,
+        PULL_CORRELATION_RULE,
         VALIDATOR,
         NOTIFICATION_RECIPIENTS_PROVIDER;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
index 46fcedc..781b77a 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
@@ -105,7 +105,7 @@ public class LinkingMappingItem implements MappingItem {
 
     @Override
     public MappingPurpose getPurpose() {
-        return virSchema.isReadonly() ? MappingPurpose.SYNCHRONIZATION : MappingPurpose.BOTH;
+        return virSchema.isReadonly() ? MappingPurpose.PULL : MappingPurpose.BOTH;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
new file mode 100644
index 0000000..da82cb7
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.policy;
+
+import org.apache.syncope.common.lib.policy.PullPolicySpec;
+import org.apache.syncope.core.persistence.api.entity.Policy;
+
+public interface PullPolicy extends Policy {
+
+    PullPolicySpec getSpecification();
+
+    void setSpecification(PullPolicySpec spec);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/SyncPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/SyncPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/SyncPolicy.java
deleted file mode 100644
index 78a9882..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/SyncPolicy.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.policy;
-
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.Policy;
-
-public interface SyncPolicy extends Policy {
-
-    SyncPolicySpec getSpecification();
-
-    void setSpecification(SyncPolicySpec spec);
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
index 32759cd..7b5147e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -28,7 +28,7 @@ import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
+import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 
 public interface ExternalResource extends AnnotatedEntity<String> {
@@ -57,9 +57,9 @@ public interface ExternalResource extends AnnotatedEntity<String> {
 
     void setPasswordPolicy(PasswordPolicy passwordPolicy);
 
-    SyncPolicy getSyncPolicy();
+    PullPolicy getPullPolicy();
 
-    void setSyncPolicy(SyncPolicy syncPolicy);
+    void setPullPolicy(PullPolicy pullPolicy);
 
     TraceLevel getCreateTraceLevel();
 
@@ -73,9 +73,9 @@ public interface ExternalResource extends AnnotatedEntity<String> {
 
     void setDeleteTraceLevel(TraceLevel deleteTraceLevel);
 
-    TraceLevel getSyncTraceLevel();
+    TraceLevel getPullTraceLevel();
 
-    void setSyncTraceLevel(TraceLevel syncTraceLevel);
+    void setPullTraceLevel(TraceLevel pullTraceLevel);
 
     List<String> getPropagationActionsClassNames();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplatePullTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplatePullTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplatePullTask.java
new file mode 100644
index 0000000..10eafe5
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplatePullTask.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.task;
+
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+
+public interface AnyTemplatePullTask extends AnyTemplate {
+
+    PullTask getPullTask();
+
+    void setPullTask(PullTask pullTask);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplateSyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplateSyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplateSyncTask.java
deleted file mode 100644
index 82d7e2e..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplateSyncTask.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.task;
-
-import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
-
-public interface AnyTemplateSyncTask extends AnyTemplate {
-
-    SyncTask getSyncTask();
-
-    void setSyncTask(SyncTask syncTask);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
index 296de84..ac2d2f7 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
@@ -51,8 +51,8 @@ public interface ProvisioningTask extends SchedTask {
 
     void setPerformUpdate(boolean performUpdate);
 
-    boolean isSyncStatus();
+    boolean isPullStatus();
 
-    void setSyncStatus(boolean syncStatus);
+    void setPullStatus(boolean pullStatus);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
new file mode 100644
index 0000000..52c5b93
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.task;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.PullMode;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+
+public interface PullTask extends ProvisioningTask {
+
+    PullMode getPullMode();
+
+    void setPullMode(PullMode pullMode);
+
+    String getReconciliationFilterBuilderClassName();
+
+    void setReconciliationFilterBuilderClassName(String reconciliationFilterBuilderClassName);
+
+    Realm getDestinatioRealm();
+
+    void setDestinationRealm(Realm destinationRealm);
+
+    boolean add(AnyTemplatePullTask template);
+
+    AnyTemplatePullTask getTemplate(AnyType anyType);
+
+    List<? extends AnyTemplatePullTask> getTemplates();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
deleted file mode 100644
index 127b1cf..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.task;
-
-import java.util.List;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-
-public interface SyncTask extends ProvisioningTask {
-
-    SyncMode getSyncMode();
-
-    void setSyncMode(SyncMode syncMode);
-
-    String getReconciliationFilterBuilderClassName();
-
-    void setReconciliationFilterBuilderClassName(String reconciliationFilterBuilderClassName);
-
-    Realm getDestinatioRealm();
-
-    void setDestinationRealm(Realm destinationRealm);
-
-    boolean add(AnyTemplateSyncTask template);
-
-    AnyTemplateSyncTask getTemplate(AnyType anyType);
-
-    List<? extends AnyTemplateSyncTask> getTemplates();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 392f357..44c6e08 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -106,8 +106,8 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
                 query.append("passwordPolicy");
                 break;
 
-            case SYNC:
-                query.append("syncPolicy");
+            case PULL:
+                query.append("pullPolicy");
                 break;
 
             default:
@@ -198,7 +198,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         }
 
         taskDAO.deleteAll(resource, TaskType.PROPAGATION);
-        taskDAO.deleteAll(resource, TaskType.SYNCHRONIZATION);
+        taskDAO.deleteAll(resource, TaskType.PULL);
         taskDAO.deleteAll(resource, TaskType.PUSH);
 
         for (AnyObject anyObject : anyObjectDAO.findByResource(resource)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index ecd5050..5100de8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -117,7 +117,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public <T extends Policy> List<Realm> findByPolicy(final T policy) {
-        if (policy.getType() == PolicyType.SYNC) {
+        if (policy.getType() == PolicyType.PULL) {
             return Collections.<Realm>emptyList();
         }
 


[02/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
new file mode 100644
index 0000000..dc3df18
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -0,0 +1,853 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.patch.DeassociationPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
+import org.apache.syncope.common.lib.types.PullMode;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+import org.apache.syncope.common.rest.api.beans.TaskQuery;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions;
+import org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions;
+import org.apache.syncope.fit.ActivitiDetector;
+import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
+import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
+import org.apache.syncope.fit.core.reference.TestPullActions;
+import org.apache.syncope.fit.core.reference.TestPullRule;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PullTaskITCase extends AbstractTaskITCase {
+
+    @BeforeClass
+    public static void testPullctionsSetup() {
+        PullTaskTO pullTask = taskService.read(PULL_TASK_ID, true);
+        pullTask.getActionsClassNames().add(TestPullActions.class.getName());
+        taskService.update(pullTask);
+    }
+
+    @Test
+    public void getPullActionsClasses() {
+        Set<String> actions = syncopeService.platform().getPullActions();
+        assertNotNull(actions);
+        assertFalse(actions.isEmpty());
+    }
+
+    @Test
+    public void list() {
+        PagedResult<PullTaskTO> tasks = taskService.list(
+                new TaskQuery.Builder().type(TaskType.PULL).build());
+        assertFalse(tasks.getResult().isEmpty());
+        for (AbstractTaskTO task : tasks.getResult()) {
+            if (!(task instanceof PullTaskTO)) {
+                fail();
+            }
+        }
+    }
+
+    @Test
+    public void create() {
+        PullTaskTO task = new PullTaskTO();
+        task.setName("Test create Pull");
+        task.setDestinationRealm("/");
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
+
+        UserTO userTemplate = new UserTO();
+        userTemplate.getResources().add(RESOURCE_NAME_WS2);
+
+        userTemplate.getMemberships().add(new MembershipTO.Builder().group(8L).build());
+        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
+
+        GroupTO groupTemplate = new GroupTO();
+        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
+        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
+
+        Response response = taskService.create(task);
+        PullTaskTO actual = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
+        assertNotNull(actual);
+
+        task = taskService.read(actual.getKey(), true);
+        assertNotNull(task);
+        assertEquals(actual.getKey(), task.getKey());
+        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
+        assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
+        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
+    }
+
+    @Test
+    public void pull() throws Exception {
+        removeTestUsers();
+
+        // -----------------------------
+        // Create a new user ... it should be updated applying pull policy
+        // -----------------------------
+        UserTO inUserTO = new UserTO();
+        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
+        inUserTO.setPassword("password123");
+        String userName = "test9";
+        inUserTO.setUsername(userName);
+        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
+        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("ctype", "a type"));
+        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
+        inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
+        inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
+        inUserTO.getAuxClasses().add("csv");
+        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+        inUserTO = createUser(inUserTO).getAny();
+        assertNotNull(inUserTO);
+        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
+
+        // -----------------------------
+        try {
+            int usersPre = userService.list(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPre);
+
+            execProvisioningTask(taskService, PULL_TASK_ID, 50, false);
+
+            // after execution of the pull task the user data should have been pulled from CSV
+            // and processed by user template
+            UserTO userTO = userService.read(inUserTO.getKey());
+            assertNotNull(userTO);
+            assertEquals(userName, userTO.getUsername());
+            assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+                    ? "active" : "created", userTO.getStatus());
+            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
+            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+
+            // Matching --> Update (no link)
+            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+            // check for user template
+            userTO = readUser("test7");
+            assertNotNull(userTO);
+            assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("ctype").getValues().get(0));
+            assertEquals(3, userTO.getResources().size());
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+            assertEquals(1, userTO.getMemberships().size());
+            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
+
+            // Unmatching --> Assign (link) - SYNCOPE-658
+            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), new Predicate<AttrTO>() {
+
+                @Override
+                public boolean evaluate(final AttrTO attributeTO) {
+                    return "csvuserid".equals(attributeTO.getSchema());
+                }
+            }));
+
+            userTO = readUser("test8");
+            assertNotNull(userTO);
+            assertEquals("TYPE_8", userTO.getPlainAttrMap().get("ctype").getValues().get(0));
+
+            // Check for ignored user - SYNCOPE-663
+            try {
+                readUser("test2");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+            }
+
+            // check for pull results
+            int usersPost = userService.list(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
+            assertNotNull(usersPost);
+            assertEquals(usersPre + 8, usersPost);
+
+            // Check for issue 215:
+            // * expected disabled user test1
+            // * expected enabled user test3
+            userTO = readUser("test1");
+            assertNotNull(userTO);
+            assertEquals("suspended", userTO.getStatus());
+
+            userTO = readUser("test3");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+
+            Set<Long> otherPullTaskKeys = new HashSet<>();
+            otherPullTaskKeys.add(25L);
+            otherPullTaskKeys.add(26L);
+            execProvisioningTasks(taskService, otherPullTaskKeys, 50, false);
+
+            // Matching --> UNLINK
+            assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+            assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void dryRun() {
+        ExecTO execution = execProvisioningTask(taskService, PULL_TASK_ID, 50, true);
+        assertEquals(
+                "Execution of " + execution.getRefDesc() + " failed with message " + execution.getMessage(),
+                "SUCCESS", execution.getStatus());
+    }
+
+    @Test
+    public void reconcileFromDB() {
+        UserTO userTO = null;
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        try {
+            ExecTO execution = execProvisioningTask(taskService, 7L, 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals("suspended", userTO.getStatus());
+
+            // enable user on external resource
+            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE id='testuser1'");
+
+            // re-execute the same PullTask: now user must be active
+            execution = execProvisioningTask(taskService, 7L, 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser1");
+            assertNotNull(userTO);
+            assertEquals("active", userTO.getStatus());
+        } finally {
+            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE id='testUser1'");
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    /**
+     * Clean Syncope and LDAP resource status.
+     */
+    private void ldapCleanup() {
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        if (matchingGroups.getSize() > 0) {
+            for (GroupTO group : matchingGroups.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(group.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                groupService.deassociate(deassociationPatch);
+                groupService.delete(group.getKey());
+            }
+        }
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("pullFromLDAP").query()).
+                build());
+        if (matchingUsers.getSize() > 0) {
+            for (UserTO user : matchingUsers.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(user.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
+                userService.deassociate(deassociationPatch);
+                userService.delete(user.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void reconcileFromLDAP() {
+        // First of all, clear any potential conflict with existing user / group
+        ldapCleanup();
+
+        // 0. pull
+        ExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
+
+        // 1. verify execution status
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 2. verify that pulled group is found
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
+        assertNotNull(matchingGroups);
+        assertEquals(1, matchingGroups.getResult().size());
+
+        // 3. verify that pulled user is found
+        PagedResult<UserTO> matchingUsers = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("pullFromLDAP").query()).
+                build());
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.getResult().size());
+
+        // Check for SYNCOPE-436
+        assertEquals("pullFromLDAP",
+                matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+        // Check for SYNCOPE-270
+        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
+        // Check for SYNCOPE-123
+        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
+
+        GroupTO groupTO = matchingGroups.getResult().iterator().next();
+        assertNotNull(groupTO);
+        assertEquals("testLDAPGroup", groupTO.getName());
+        assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
+        assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
+        assertNull(groupTO.getGroupOwner());
+
+        // SYNCOPE-317
+        execProvisioningTask(taskService, 11L, 50, false);
+    }
+
+    @Test
+    public void reconcileFromScriptedSQL() {
+        // 0. reset sync token and set MappingItemTransformer
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+        ResourceTO originalResource = SerializationUtils.clone(resource);
+        ProvisionTO provision = resource.getProvision("PRINTER");
+        assertNotNull(provision);
+
+        try {
+            provision.setSyncToken(null);
+
+            MappingItemTO mappingItem = IterableUtils.find(
+                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+
+                @Override
+                public boolean evaluate(final MappingItemTO object) {
+                    return "location".equals(object.getIntAttrName());
+                }
+            });
+            assertNotNull(mappingItem);
+            mappingItem.getMappingItemTransformerClassNames().clear();
+            mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
+
+            resourceService.update(resource);
+
+            // 1. create printer on external resource
+            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("pull");
+            String originalLocation = anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
+            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            anyObjectTO = createAnyObject(anyObjectTO).getAny();
+            assertNotNull(anyObjectTO);
+
+            // 2. verify that PrefixMappingItemTransformer was applied during propagation
+            // (location starts with given prefix on external resource)
+            ConnObjectTO connObjectTO = resourceService.
+                    readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
+            assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+            assertTrue(connObjectTO.getPlainAttrMap().get("LOCATION").getValues().get(0).
+                    startsWith(PrefixMappingItemTransformer.PREFIX));
+
+            // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
+            PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("pull*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+            for (AnyObjectTO printer : matchingPrinters.getResult()) {
+                DeassociationPatch deassociationPatch = new DeassociationPatch();
+                deassociationPatch.setKey(printer.getKey());
+                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
+                deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+                anyObjectService.deassociate(deassociationPatch);
+                anyObjectService.delete(printer.getKey());
+            }
+
+            // 4. pull
+            execProvisioningTask(taskService, 28L, 50, false);
+
+            // 5. verify that printer was re-created in Syncope (implies that location does not start with given prefix,
+            // hence PrefixMappingItemTransformer was applied during pull)
+            matchingPrinters = anyObjectService.search(
+                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                            is("location").equalTo("pull*").query()).build());
+            assertTrue(matchingPrinters.getSize() > 0);
+
+            // 6. verify that synctoken was updated
+            assertNotNull(
+                    resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
+        } finally {
+            resourceService.update(originalResource);
+        }
+    }
+
+    @Test
+    public void filteredReconciliation() {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        PullTaskTO task = null;
+        UserTO userTO = null;
+        try {
+            // 1. create 2 users on testpull
+            jdbcTemplate.execute("INSERT INTO testpull VALUES (1001, 'user1', 'Doe', 'mail1@apache.org')");
+            jdbcTemplate.execute("INSERT INTO testpull VALUES (1002, 'user2', 'Rossi', 'mail2@apache.org')");
+
+            // 2. create new pull task for test-db, with reconciliation filter (surname 'Rossi') 
+            task = taskService.read(10L, true);
+            task.setPullMode(PullMode.FILTERED_RECONCILIATION);
+            task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
+            Response response = taskService.create(task);
+            task = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
+            assertNotNull(task);
+            assertEquals(
+                    TestReconciliationFilterBuilder.class.getName(),
+                    task.getReconciliationFilterBuilderClassName());
+
+            // 3. exec task
+            ExecTO execution = execProvisioningTask(taskService, task.getKey(), 50, false);
+            assertNotNull(execution.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            // 4. verify that only enabled user was pulled
+            userTO = readUser("user2");
+            assertNotNull(userTO);
+
+            try {
+                readUser("user1");
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.NotFound, e.getType());
+            }
+        } finally {
+            jdbcTemplate.execute("DELETE FROM testpull WHERE id = 1001");
+            jdbcTemplate.execute("DELETE FROM testpull WHERE id = 1002");
+            if (task != null && task.getKey() != 7L) {
+                taskService.delete(task.getKey());
+            }
+            if (userTO != null) {
+                userService.delete(userTO.getKey());
+            }
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE68() {
+        //-----------------------------
+        // Create a new user ... it should be updated applying pull policy
+        //-----------------------------
+        UserTO userTO = new UserTO();
+        userTO.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO.setPassword("password123");
+        userTO.setUsername("testuser2");
+
+        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
+        userTO.getPlainAttrs().add(attrTO("ctype", "a type"));
+        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
+        userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
+        userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
+
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
+        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+
+        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+        assertEquals("testuser2", userTO.getUsername());
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals(3, userTO.getResources().size());
+        //-----------------------------
+
+        try {
+            //-----------------------------
+            //  add user template
+            //-----------------------------
+            UserTO template = new UserTO();
+
+            template.getMemberships().add(new MembershipTO.Builder().group(10L).build());
+
+            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+            //-----------------------------
+
+            // Update pull task
+            PullTaskTO task = taskService.read(9L, true);
+            assertNotNull(task);
+
+            task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+            taskService.update(task);
+            PullTaskTO actual = taskService.read(task.getKey(), true);
+            assertNotNull(actual);
+            assertEquals(task.getKey(), actual.getKey());
+            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
+            assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
+
+            ExecTO execution = execProvisioningTask(taskService, actual.getKey(), 50, false);
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+            userTO = readUser("testuser2");
+            assertNotNull(userTO);
+            assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+            assertEquals(2, userTO.getMemberships().size());
+            assertEquals(4, userTO.getResources().size());
+        } finally {
+            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
+            assertNotNull(dUserTO);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE230() {
+        // 1. read PullTask for resource-db-pull (table TESTPULL on external H2)
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 3. read e-mail address for user created by the PullTask first execution
+        UserTO userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+
+        // 4. update TESTPULL on external H2 by changing e-mail address
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        jdbcTemplate.execute("UPDATE TESTPULL SET email='updatedSYNCOPE230@syncope.apache.org'");
+
+        // 5. re-execute the PullTask
+        execProvisioningTask(taskService, 10L, 50, false);
+
+        // 6. verify that the e-mail was updated
+        userTO = readUser("issuesyncope230");
+        assertNotNull(userTO);
+        email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+        assertNotNull(email);
+        assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
+    }
+
+    @Test
+    public void issueSYNCOPE258() {
+        // -----------------------------
+        // Add a custom correlation rule
+        // -----------------------------
+        PullPolicyTO policyTO = policyService.read(9L);
+        policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestPullRule.class.getName());
+        policyService.update(policyTO);
+        // -----------------------------
+
+        PullTaskTO task = new PullTaskTO();
+        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        task.setName("Test Pull Rule");
+        task.setActive(true);
+        task.setResource(RESOURCE_NAME_WS2);
+        task.setPullMode(PullMode.FULL_RECONCILIATION);
+        task.setPerformCreate(true);
+        task.setPerformDelete(true);
+        task.setPerformUpdate(true);
+
+        Response response = taskService.create(task);
+        task = getObject(response.getLocation(), TaskService.class, PullTaskTO.class);
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        createUser(userTO);
+
+        userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+
+        // change email in order to unmatch the second user
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", "s258@apache.org"));
+
+        userService.update(userPatch);
+
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        PullTaskTO executed = taskService.read(task.getKey(), true);
+        assertEquals(1, executed.getExecutions().size());
+
+        // asser for just one match
+        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
+                executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
+    }
+
+    @Test
+    public void issueSYNCOPE272() {
+        removeTestUsers();
+
+        // create user with testdb resource
+        UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        userTO = result.getAny();
+        try {
+            assertNotNull(userTO);
+            assertEquals(1, result.getPropagationStatuses().size());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+            ExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, false);
+
+            assertNotNull(taskExecTO.getStatus());
+            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
+
+            userTO = userService.read(userTO.getKey());
+            assertNotNull(userTO);
+            assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
+        } finally {
+            removeTestUsers();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE307() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
+        userTO.setUsername("test0");
+        userTO.getPlainAttrMap().get("firstname").getValues().clear();
+        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
+        userTO.getAuxClasses().add("csv");
+
+        AttrTO csvuserid = new AttrTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.getDerAttrs().add(csvuserid);
+
+        userTO.getResources().clear();
+        userTO.getResources().add(RESOURCE_NAME_WS2);
+
+        userTO = createUser(userTO).getAny();
+        assertNotNull(userTO);
+
+        userTO = userService.read(userTO.getKey());
+        assertTrue(userTO.getVirAttrMap().isEmpty());
+
+        // Update pull task
+        PullTaskTO task = taskService.read(12L, true);
+        assertNotNull(task);
+
+        UserTO template = new UserTO();
+        template.setPassword("'password123'");
+        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
+        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
+
+        task.getTemplates().put(AnyTypeKind.USER.name(), template);
+
+        taskService.update(task);
+
+        // exec task: one user from CSV will match the user created above and template will be applied
+        execProvisioningTask(taskService, task.getKey(), 50, false);
+
+        // check that template was successfully applied...
+        userTO = userService.read(userTO.getKey());
+        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+        // ...and that propagation to db succeeded
+        try {
+            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+            String value = jdbcTemplate.queryForObject(
+                    "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO.getKey());
+            assertEquals("virtualvalue", value);
+        } catch (EmptyResultDataAccessException e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE313DB() throws Exception {
+        // 1. create user in DB
+        UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
+        user.setPassword("security123");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. Check that the DB resource has the correct password
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 3. Update the password in the DB
+        String newCleanPassword = "new-security";
+        String newPassword = Encryptor.getInstance().encode(newCleanPassword, CipherAlgorithm.SHA1);
+        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
+
+        // 4. Pull the user from the resource
+        PullTaskTO pullTask = new PullTaskTO();
+        pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        pullTask.setName("DB Pull Task");
+        pullTask.setActive(true);
+        pullTask.setPerformCreate(true);
+        pullTask.setPerformUpdate(true);
+        pullTask.setPullMode(PullMode.FULL_RECONCILIATION);
+        pullTask.setResource(RESOURCE_NAME_TESTDB);
+        pullTask.getActionsClassNames().add(DBPasswordPullActions.class.getName());
+        Response taskResponse = taskService.create(pullTask);
+
+        PullTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, PullTaskTO.class);
+        assertNotNull(actual);
+
+        pullTask = taskService.read(actual.getKey(), true);
+        assertNotNull(pullTask);
+        assertEquals(actual.getKey(), pullTask.getKey());
+        assertEquals(actual.getJobDelegateClassName(), pullTask.getJobDelegateClassName());
+
+        ExecTO execution = execProvisioningTask(taskService, pullTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 5. Test the pulled user
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 6. Delete PullTask + user
+        taskService.delete(pullTask.getKey());
+        deleteUser(user.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE313LDAP() throws Exception {
+        // First of all, clear any potential conflict with existing user / group
+        ldapCleanup();
+
+        // 1. create user in LDAP
+        String oldCleanPassword = "security123";
+        UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
+        user.setPassword(oldCleanPassword);
+        user.getResources().add(RESOURCE_NAME_LDAP);
+        user = createUser(user).getAny();
+        assertNotNull(user);
+        assertFalse(user.getResources().isEmpty());
+
+        // 2. request to change password only on Syncope and not on LDAP
+        String newCleanPassword = "new-security123";
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(user.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value(newCleanPassword).build());
+        user = updateUser(userPatch).getAny();
+
+        // 3. Check that the Syncope user now has the changed password
+        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
+        assertNotNull(self);
+
+        // 4. Check that the LDAP resource has the old password
+        ConnObjectTO connObject =
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
+        assertNotNull(getLdapRemoteObject(
+                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+                oldCleanPassword,
+                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+        // 5. Update the LDAP Connector to retrieve passwords
+        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
+        ConnInstanceTO resourceConnector = connectorService.read(
+                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
+        ConnConfProperty property = resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
+        property.getValues().clear();
+        property.getValues().add(Boolean.TRUE);
+        connectorService.update(resourceConnector);
+
+        // 6. Pull the user from the resource
+        PullTaskTO pullTask = new PullTaskTO();
+        pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
+        pullTask.setName("LDAP Pull Task");
+        pullTask.setActive(true);
+        pullTask.setPerformCreate(true);
+        pullTask.setPerformUpdate(true);
+        pullTask.setPullMode(PullMode.FULL_RECONCILIATION);
+        pullTask.setResource(RESOURCE_NAME_LDAP);
+        pullTask.getActionsClassNames().add(LDAPPasswordPullActions.class.getName());
+        Response taskResponse = taskService.create(pullTask);
+
+        pullTask = getObject(taskResponse.getLocation(), TaskService.class, PullTaskTO.class);
+        assertNotNull(pullTask);
+
+        ExecTO execution = execProvisioningTask(taskService, pullTask.getKey(), 50, false);
+        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
+
+        // 7. Test the pulled user
+        self = clientFactory.create(user.getUsername(), oldCleanPassword).self();
+        assertNotNull(self);
+
+        // 8. Delete PullTask + user + reset the connector
+        taskService.delete(pullTask.getKey());
+        property.getValues().clear();
+        property.getValues().add(Boolean.FALSE);
+        connectorService.update(resourceConnector);
+        deleteUser(user.getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
index 9b5a7ed..56d8ec3 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportTemplateITCase.java
@@ -39,12 +39,6 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 @FixMethodOrder(MethodSorters.JVM)
 public class ReportTemplateITCase extends AbstractITCase {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index cc6706f..b3010ff 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -214,7 +214,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.GroupKey);
         item.setExtAttrName("groupId");
         item.setConnObjectKey(true);
-        item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+        item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
         Response response = resourceService.create(resourceTO);
@@ -225,7 +225,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
         assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping());
         assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems());
-        assertEquals(MappingPurpose.SYNCHRONIZATION,
+        assertEquals(MappingPurpose.PULL,
                 actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getConnObjectKeyItem().getPurpose());
         assertEquals(MappingPurpose.PROPAGATION,
                 actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
index cac3810..1b0825d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.TaskType;
@@ -66,7 +66,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
                 taskService.list(new TaskQuery.Builder().type(TaskType.SCHEDULED).build());
         assertFalse(tasks.getResult().isEmpty());
         for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
+            if (!(task instanceof SchedTaskTO) || task instanceof PullTaskTO || task instanceof PushTaskTO) {
                 fail();
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index d18c94b..0e6a991 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.Collection;
-import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
@@ -223,7 +222,7 @@ public class SearchITCase extends AbstractITCase {
                 build());
         assertNotNull(matchingUsers);
         assertEquals(2, matchingUsers.getPage());
-        assertEquals(2, matchingUsers.getResult().size());
+        assertFalse(matchingUsers.getResult().isEmpty());
     }
 
     @Test
@@ -414,18 +413,23 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE768() {
-        final List<UserTO> usersWithType = userService.search(
+        int usersWithNullable = userService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("ctype").notNullValue().query()).build()).
-                getResult();
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("ctype").nullValue().query()).build()).
+                getTotalCount();
+        assertTrue(usersWithNullable > 0);
 
-        assertFalse(usersWithType.isEmpty());
+        int nonOrdered = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").notNullValue().query()).build()).
+                getTotalCount();
+        assertTrue(nonOrdered > 0);
 
-        final PagedResult<UserTO> matchedUsers = userService.search(
+        int orderedByNullable = userService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").notNullValue().query()).
-                orderBy(SyncopeClient.getOrderByClauseBuilder().asc("ctype").build()).build());
-
-        assertTrue(matchedUsers.getResult().size() > usersWithType.size());
+                orderBy(SyncopeClient.getOrderByClauseBuilder().asc("ctype").build()).build()).
+                getTotalCount();
+        assertEquals(nonOrdered, orderedByNullable);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
deleted file mode 100644
index 87bec8b..0000000
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core;
-
-import org.apache.syncope.fit.ActivitiDetector;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.patch.DeassociationPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
-import org.apache.syncope.common.lib.to.ExecTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
-import org.apache.syncope.common.lib.types.SyncMode;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
-import org.apache.syncope.common.rest.api.beans.TaskQuery;
-import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.spring.security.Encryptor;
-import org.apache.syncope.core.provisioning.java.syncpull.DBPasswordSyncActions;
-import org.apache.syncope.core.provisioning.java.syncpull.LDAPPasswordSyncActions;
-import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
-import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
-import org.apache.syncope.fit.core.reference.TestSyncActions;
-import org.apache.syncope.fit.core.reference.TestSyncRule;
-import org.identityconnectors.framework.common.objects.Name;
-import org.junit.BeforeClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-@FixMethodOrder(MethodSorters.JVM)
-public class SyncTaskITCase extends AbstractTaskITCase {
-
-    @BeforeClass
-    public static void testSyncActionsSetup() {
-        SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID, true);
-        syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
-        taskService.update(syncTask);
-    }
-
-    @Test
-    public void getSyncActionsClasses() {
-        Set<String> actions = syncopeService.platform().getSyncActions();
-        assertNotNull(actions);
-        assertFalse(actions.isEmpty());
-    }
-
-    @Test
-    public void list() {
-        PagedResult<SyncTaskTO> tasks = taskService.list(
-                new TaskQuery.Builder().type(TaskType.SYNCHRONIZATION).build());
-        assertFalse(tasks.getResult().isEmpty());
-        for (AbstractTaskTO task : tasks.getResult()) {
-            if (!(task instanceof SyncTaskTO)) {
-                fail();
-            }
-        }
-    }
-
-    @Test
-    public void create() {
-        SyncTaskTO task = new SyncTaskTO();
-        task.setName("Test create Sync");
-        task.setDestinationRealm("/");
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-
-        UserTO userTemplate = new UserTO();
-        userTemplate.getResources().add(RESOURCE_NAME_WS2);
-
-        userTemplate.getMemberships().add(new MembershipTO.Builder().group(8L).build());
-        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
-
-        GroupTO groupTemplate = new GroupTO();
-        groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
-        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
-
-        Response response = taskService.create(task);
-        SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        task = taskService.read(actual.getKey(), true);
-        assertNotNull(task);
-        assertEquals(actual.getKey(), task.getKey());
-        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
-        assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
-        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
-    }
-
-    @Test
-    public void sync() throws Exception {
-        removeTestUsers();
-
-        // -----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        // -----------------------------
-        UserTO inUserTO = new UserTO();
-        inUserTO.setRealm(SyncopeConstants.ROOT_REALM);
-        inUserTO.setPassword("password123");
-        String userName = "test9";
-        inUserTO.setUsername(userName);
-        inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
-        inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("ctype", "a type"));
-        inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
-        inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
-        inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
-        inUserTO.getAuxClasses().add("csv");
-        inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        inUserTO = createUser(inUserTO).getAny();
-        assertNotNull(inUserTO);
-        assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
-
-        // -----------------------------
-        try {
-            int usersPre = userService.list(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPre);
-
-            execProvisioningTask(taskService, SYNC_TASK_ID, 50, false);
-
-            // after execution of the sync task the user data should have been synced from CSV
-            // and processed by user template
-            UserTO userTO = userService.read(inUserTO.getKey());
-            assertNotNull(userTO);
-            assertEquals(userName, userTO.getUsername());
-            assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
-                    ? "active" : "created", userTO.getStatus());
-            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
-            assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-
-            // Matching --> Update (no link)
-            assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
-
-            // check for user template
-            userTO = readUser("test7");
-            assertNotNull(userTO);
-            assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("ctype").getValues().get(0));
-            assertEquals(3, userTO.getResources().size());
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
-            assertEquals(1, userTO.getMemberships().size());
-            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
-
-            // Unmatching --> Assign (link) - SYNCOPE-658
-            assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
-            assertEquals(1, IterableUtils.countMatches(userTO.getDerAttrs(), new Predicate<AttrTO>() {
-
-                @Override
-                public boolean evaluate(final AttrTO attributeTO) {
-                    return "csvuserid".equals(attributeTO.getSchema());
-                }
-            }));
-
-            userTO = readUser("test8");
-            assertNotNull(userTO);
-            assertEquals("TYPE_8", userTO.getPlainAttrMap().get("ctype").getValues().get(0));
-
-            // Check for ignored user - SYNCOPE-663
-            try {
-                readUser("test2");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
-            }
-
-            // check for sync results
-            int usersPost = userService.list(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    page(1).size(1).build()).getTotalCount();
-            assertNotNull(usersPost);
-            assertEquals(usersPre + 8, usersPost);
-
-            // Check for issue 215:
-            // * expected disabled user test1
-            // * expected enabled user test2
-            userTO = readUser("test1");
-            assertNotNull(userTO);
-            assertEquals("suspended", userTO.getStatus());
-
-            userTO = readUser("test3");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-
-            Set<Long> otherSyncTaskKeys = new HashSet<>();
-            otherSyncTaskKeys.add(25L);
-            otherSyncTaskKeys.add(26L);
-            execProvisioningTasks(taskService, otherSyncTaskKeys, 50, false);
-
-            // Matching --> UNLINK
-            assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
-            assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void dryRun() {
-        ExecTO execution = execProvisioningTask(taskService, SYNC_TASK_ID, 50, true);
-        assertEquals(
-                "Execution of " + execution.getRefDesc() + " failed with message " + execution.getMessage(),
-                "SUCCESS", execution.getStatus());
-    }
-
-    @Test
-    public void reconcileFromDB() {
-        UserTO userTO = null;
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        try {
-            ExecTO execution = execProvisioningTask(taskService, 7L, 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals("suspended", userTO.getStatus());
-
-            // enable user on external resource
-            jdbcTemplate.execute("UPDATE TEST SET status=TRUE WHERE id='testuser1'");
-
-            // re-execute the same SyncTask: now user must be active
-            execution = execProvisioningTask(taskService, 7L, 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser1");
-            assertNotNull(userTO);
-            assertEquals("active", userTO.getStatus());
-        } finally {
-            jdbcTemplate.execute("UPDATE TEST SET status=FALSE WHERE id='testUser1'");
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    /**
-     * Clean Syncope and LDAP resource status.
-     */
-    private void ldapCleanup() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        if (matchingGroups.getSize() > 0) {
-            for (GroupTO group : matchingGroups.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(group.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                groupService.deassociate(deassociationPatch);
-                groupService.delete(group.getKey());
-            }
-        }
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        if (matchingUsers.getSize() > 0) {
-            for (UserTO user : matchingUsers.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(user.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
-                userService.deassociate(deassociationPatch);
-                userService.delete(user.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void reconcileFromLDAP() {
-        // First of all, clear any potential conflict with existing user / group
-        ldapCleanup();
-
-        // 0. synchronize
-        ExecTO execution = execProvisioningTask(taskService, 11L, 50, false);
-
-        // 1. verify execution status
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 2. verify that synchronized group is found
-        PagedResult<GroupTO> matchingGroups = groupService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
-                build());
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.getResult().size());
-
-        // 3. verify that synchronized user is found
-        PagedResult<UserTO> matchingUsers = userService.search(
-                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
-                build());
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.getResult().size());
-
-        // Check for SYNCOPE-436
-        assertEquals("syncFromLDAP",
-                matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
-        // Check for SYNCOPE-270
-        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
-        // Check for SYNCOPE-123
-        assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
-
-        GroupTO groupTO = matchingGroups.getResult().iterator().next();
-        assertNotNull(groupTO);
-        assertEquals("testLDAPGroup", groupTO.getName());
-        assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
-        assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
-        assertNull(groupTO.getGroupOwner());
-
-        // SYNCOPE-317
-        execProvisioningTask(taskService, 11L, 50, false);
-    }
-
-    @Test
-    public void reconcileFromScriptedSQL() {
-        // 0. reset sync token and set MappingItemTransformer
-        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
-        ResourceTO originalResource = SerializationUtils.clone(resource);
-        ProvisionTO provision = resource.getProvision("PRINTER");
-        assertNotNull(provision);
-
-        try {
-            provision.setSyncToken(null);
-
-            MappingItemTO mappingItem = IterableUtils.find(
-                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                @Override
-                public boolean evaluate(final MappingItemTO object) {
-                    return "location".equals(object.getIntAttrName());
-                }
-            });
-            assertNotNull(mappingItem);
-            mappingItem.getMappingItemTransformerClassNames().clear();
-            mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
-
-            resourceService.update(resource);
-
-            // 1. create printer on external resource
-            AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
-            String originalLocation = anyObjectTO.getPlainAttrMap().get("location").getValues().get(0);
-            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            anyObjectTO = createAnyObject(anyObjectTO).getAny();
-            assertNotNull(anyObjectTO);
-
-            // 2. verify that PrefixMappingItemTransformer was applied during propagation
-            // (location starts with given prefix on external resource)
-            ConnObjectTO connObjectTO = resourceService.
-                    readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
-            assertFalse(anyObjectTO.getPlainAttrMap().get("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-            assertTrue(connObjectTO.getPlainAttrMap().get("LOCATION").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
-
-            // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
-            PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-            for (AnyObjectTO printer : matchingPrinters.getResult()) {
-                DeassociationPatch deassociationPatch = new DeassociationPatch();
-                deassociationPatch.setKey(printer.getKey());
-                deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
-                deassociationPatch.getResources().add(RESOURCE_NAME_DBSCRIPTED);
-                anyObjectService.deassociate(deassociationPatch);
-                anyObjectService.delete(printer.getKey());
-            }
-
-            // 4. synchronize
-            execProvisioningTask(taskService, 28L, 50, false);
-
-            // 5. verify that printer was re-created in Syncope (implies that location does not start with given prefix,
-            // hence PrefixMappingItemTransformer was applied during sync)
-            matchingPrinters = anyObjectService.search(
-                    new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
-                            is("location").equalTo("sync*").query()).build());
-            assertTrue(matchingPrinters.getSize() > 0);
-
-            // 6. verify that synctoken was updated
-            assertNotNull(
-                    resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
-        } finally {
-            resourceService.update(originalResource);
-        }
-    }
-
-    @Test
-    public void filteredReconciliation() {
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        SyncTaskTO task = null;
-        UserTO userTO = null;
-        try {
-            // 1. create 2 users on testsync
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1001, 'user1', 'Doe', 'mail1@apache.org')");
-            jdbcTemplate.execute("INSERT INTO testsync VALUES (1002, 'user2', 'Rossi', 'mail2@apache.org')");
-
-            // 2. create new sync task for test-db, with reconciliation filter (surname 'Rossi') 
-            task = taskService.read(10L, true);
-            task.setSyncMode(SyncMode.FILTERED_RECONCILIATION);
-            task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName());
-            Response response = taskService.create(task);
-            task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-            assertNotNull(task);
-            assertEquals(
-                    TestReconciliationFilterBuilder.class.getName(),
-                    task.getReconciliationFilterBuilderClassName());
-
-            // 3. exec task
-            ExecTO execution = execProvisioningTask(taskService, task.getKey(), 50, false);
-            assertNotNull(execution.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            // 4. verify that only enabled user was synchronized
-            userTO = readUser("user2");
-            assertNotNull(userTO);
-
-            try {
-                readUser("user1");
-                fail();
-            } catch (SyncopeClientException e) {
-                assertEquals(ClientExceptionType.NotFound, e.getType());
-            }
-        } finally {
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1001");
-            jdbcTemplate.execute("DELETE FROM testsync WHERE id = 1002");
-            if (task != null && task.getKey() != 7L) {
-                taskService.delete(task.getKey());
-            }
-            if (userTO != null) {
-                userService.delete(userTO.getKey());
-            }
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE68() {
-        //-----------------------------
-        // Create a new user ... it should be updated applying sync policy
-        //-----------------------------
-        UserTO userTO = new UserTO();
-        userTO.setRealm(SyncopeConstants.ROOT_REALM);
-        userTO.setPassword("password123");
-        userTO.setUsername("testuser2");
-
-        userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
-        userTO.getPlainAttrs().add(attrTO("ctype", "a type"));
-        userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
-        userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
-        userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
-
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
-        userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-
-        userTO.getMemberships().add(new MembershipTO.Builder().group(7L).build());
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-        assertEquals("testuser2", userTO.getUsername());
-        assertEquals(1, userTO.getMemberships().size());
-        assertEquals(3, userTO.getResources().size());
-        //-----------------------------
-
-        try {
-            //-----------------------------
-            //  add user template
-            //-----------------------------
-            UserTO template = new UserTO();
-
-            template.getMemberships().add(new MembershipTO.Builder().group(10L).build());
-
-            template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
-            //-----------------------------
-
-            // Update sync task
-            SyncTaskTO task = taskService.read(9L, true);
-            assertNotNull(task);
-
-            task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-            taskService.update(task);
-            SyncTaskTO actual = taskService.read(task.getKey(), true);
-            assertNotNull(actual);
-            assertEquals(task.getKey(), actual.getKey());
-            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
-            assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
-
-            ExecTO execution = execProvisioningTask(taskService, actual.getKey(), 50, false);
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-            userTO = readUser("testuser2");
-            assertNotNull(userTO);
-            assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
-            assertEquals(2, userTO.getMemberships().size());
-            assertEquals(4, userTO.getResources().size());
-        } finally {
-            UserTO dUserTO = deleteUser(userTO.getKey()).getAny();
-            assertNotNull(dUserTO);
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE230() {
-        // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 3. read e-mail address for user created by the SyncTask first execution
-        UserTO userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-
-        // 4. update TESTSYNC on external H2 by changing e-mail address
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
-
-        // 5. re-execute the SyncTask
-        execProvisioningTask(taskService, 10L, 50, false);
-
-        // 6. verify that the e-mail was updated
-        userTO = readUser("issuesyncope230");
-        assertNotNull(userTO);
-        email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
-        assertNotNull(email);
-        assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
-    }
-
-    @Test
-    public void issueSYNCOPE258() {
-        // -----------------------------
-        // Add a custom correlation rule
-        // -----------------------------
-        SyncPolicyTO policyTO = policyService.read(9L);
-        policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
-        policyService.update(policyTO);
-        // -----------------------------
-
-        SyncTaskTO task = new SyncTaskTO();
-        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        task.setName("Test Sync Rule");
-        task.setActive(true);
-        task.setResource(RESOURCE_NAME_WS2);
-        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        task.setPerformCreate(true);
-        task.setPerformDelete(true);
-        task.setPerformUpdate(true);
-
-        Response response = taskService.create(task);
-        task = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
-
-        UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        createUser(userTO);
-
-        userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-
-        // change email in order to unmatch the second user
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(userTO.getKey());
-        userPatch.getPlainAttrs().add(attrAddReplacePatch("email", "s258@apache.org"));
-
-        userService.update(userPatch);
-
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        SyncTaskTO executed = taskService.read(task.getKey(), true);
-        assertEquals(1, executed.getExecutions().size());
-
-        // asser for just one match
-        assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
-                executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
-    }
-
-    @Test
-    public void issueSYNCOPE272() {
-        removeTestUsers();
-
-        // create user with testdb resource
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
-        userTO.getResources().add(RESOURCE_NAME_TESTDB);
-
-        ProvisioningResult<UserTO> result = createUser(userTO);
-        userTO = result.getAny();
-        try {
-            assertNotNull(userTO);
-            assertEquals(1, result.getPropagationStatuses().size());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
-
-            ExecTO taskExecTO = execProvisioningTask(taskService, 24L, 50, false);
-
-            assertNotNull(taskExecTO.getStatus());
-            assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()));
-
-            userTO = userService.read(userTO.getKey());
-            assertNotNull(userTO);
-            assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
-        } finally {
-            removeTestUsers();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE307() {
-        UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
-        userTO.setUsername("test0");
-        userTO.getPlainAttrMap().get("firstname").getValues().clear();
-        userTO.getPlainAttrMap().get("firstname").getValues().add("nome0");
-        userTO.getAuxClasses().add("csv");
-
-        AttrTO csvuserid = new AttrTO();
-        csvuserid.setSchema("csvuserid");
-        userTO.getDerAttrs().add(csvuserid);
-
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_WS2);
-
-        userTO = createUser(userTO).getAny();
-        assertNotNull(userTO);
-
-        userTO = userService.read(userTO.getKey());
-        assertTrue(userTO.getVirAttrMap().isEmpty());
-
-        // Update sync task
-        SyncTaskTO task = taskService.read(12L, true);
-        assertNotNull(task);
-
-        UserTO template = new UserTO();
-        template.setPassword("'password123'");
-        template.getResources().add(RESOURCE_NAME_DBVIRATTR);
-        template.getVirAttrs().add(attrTO("virtualdata", "'virtualvalue'"));
-
-        task.getTemplates().put(AnyTypeKind.USER.name(), template);
-
-        taskService.update(task);
-
-        // exec task: one user from CSV will match the user created above and template will be applied
-        execProvisioningTask(taskService, task.getKey(), 50, false);
-
-        // check that template was successfully applied...
-        userTO = userService.read(userTO.getKey());
-        assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ...and that propagation to db succeeded
-        try {
-            JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-            String value = jdbcTemplate.queryForObject(
-                    "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
-            assertEquals("virtualvalue", value);
-        } catch (EmptyResultDataAccessException e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void issueSYNCOPE313DB() throws Exception {
-        // 1. create user in DB
-        UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
-        user.setPassword("security123");
-        user.getResources().add(RESOURCE_NAME_TESTDB);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. Check that the DB resource has the correct password
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-        String value = jdbcTemplate.queryForObject(
-                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
-        assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
-
-        // 3. Update the password in the DB
-        String newCleanPassword = "new-security";
-        String newPassword = Encryptor.getInstance().encode(newCleanPassword, CipherAlgorithm.SHA1);
-        jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
-
-        // 4. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("DB Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_TESTDB);
-        syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(actual);
-
-        syncTask = taskService.read(actual.getKey(), true);
-        assertNotNull(syncTask);
-        assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
-
-        ExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 5. Test the sync'd user
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 6. Delete SyncTask + user
-        taskService.delete(syncTask.getKey());
-        deleteUser(user.getKey());
-    }
-
-    @Test
-    public void issueSYNCOPE313LDAP() throws Exception {
-        // First of all, clear any potential conflict with existing user / group
-        ldapCleanup();
-
-        // 1. create user in LDAP
-        String oldCleanPassword = "security123";
-        UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
-        user.setPassword(oldCleanPassword);
-        user.getResources().add(RESOURCE_NAME_LDAP);
-        user = createUser(user).getAny();
-        assertNotNull(user);
-        assertFalse(user.getResources().isEmpty());
-
-        // 2. request to change password only on Syncope and not on LDAP
-        String newCleanPassword = "new-security123";
-        UserPatch userPatch = new UserPatch();
-        userPatch.setKey(user.getKey());
-        userPatch.setPassword(new PasswordPatch.Builder().value(newCleanPassword).build());
-        user = updateUser(userPatch).getAny();
-
-        // 3. Check that the Syncope user now has the changed password
-        Pair<Map<String, Set<String>>, UserTO> self = clientFactory.create(user.getUsername(), newCleanPassword).self();
-        assertNotNull(self);
-
-        // 4. Check that the LDAP resource has the old password
-        ConnObjectTO connObject =
-                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
-        assertNotNull(getLdapRemoteObject(
-                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
-                oldCleanPassword,
-                connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
-
-        // 5. Update the LDAP Connector to retrieve passwords
-        ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
-        ConnInstanceTO resourceConnector = connectorService.read(
-                ldapResource.getConnector(), Locale.ENGLISH.getLanguage());
-        ConnConfProperty property = resourceConnector.getConfMap().get("retrievePasswordsWithSearch");
-        property.getValues().clear();
-        property.getValues().add(Boolean.TRUE);
-        connectorService.update(resourceConnector);
-
-        // 6. Sync the user from the resource
-        SyncTaskTO syncTask = new SyncTaskTO();
-        syncTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
-        syncTask.setName("LDAP Sync Task");
-        syncTask.setActive(true);
-        syncTask.setPerformCreate(true);
-        syncTask.setPerformUpdate(true);
-        syncTask.setSyncMode(SyncMode.FULL_RECONCILIATION);
-        syncTask.setResource(RESOURCE_NAME_LDAP);
-        syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
-        Response taskResponse = taskService.create(syncTask);
-
-        syncTask = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
-        assertNotNull(syncTask);
-
-        ExecTO execution = execProvisioningTask(taskService, syncTask.getKey(), 50, false);
-        assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus()));
-
-        // 7. Test the sync'd user
-        self = clientFactory.create(user.getUsername(), oldCleanPassword).self();
-        assertNotNull(self);
-
-        // 8. Delete SyncTask + user + reset the connector
-        taskService.delete(syncTask.getKey());
-        property.getValues().clear();
-        property.getValues().add(Boolean.FALSE);
-        connectorService.update(resourceConnector);
-        deleteUser(user.getKey());
-    }
-}


[04/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
deleted file mode 100644
index 464c56b..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-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.common.lib.types.PatchOperation;
-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;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.UMembership;
-import org.apache.syncope.core.provisioning.api.AuditManager;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Simple action for synchronizing LDAP groups memberships to Syncope group memberships, when the same resource is
- * configured for both users and groups.
- *
- * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
- */
-public class LDAPMembershipSyncActions extends DefaultSyncActions {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipSyncActions.class);
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    @Autowired
-    protected UserWorkflowAdapter uwfAdapter;
-
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    @Autowired
-    private PropagationTaskExecutor taskExecutor;
-
-    @Autowired
-    private NotificationManager notificationManager;
-
-    @Autowired
-    private AuditManager auditManager;
-
-    @Autowired
-    private SyncUtils syncUtils;
-
-    protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
-
-    /**
-     * Allows easy subclassing for the ConnId AD connector bundle.
-     *
-     * @param connector A Connector instance to query for the groupMemberAttribute property name
-     * @return the name of the attribute used to keep track of group memberships
-     */
-    protected String getGroupMembershipAttrName(final Connector connector) {
-        ConnConfProperty groupMembership = IterableUtils.find(connector.getConnInstance().getConf(),
-                new Predicate<ConnConfProperty>() {
-
-            @Override
-            public boolean evaluate(final ConnConfProperty property) {
-                return "groupMemberAttribute".equals(property.getSchema().getName())
-                        && property.getValues() != null && !property.getValues().isEmpty();
-            }
-        });
-
-        return groupMembership == null
-                ? "uniquemember"
-                : (String) groupMembership.getValues().get(0);
-    }
-
-    /**
-     * Keep track of members of the group being updated <b>before</b> actual update takes place. This is not needed on
-     * <ul> <li>beforeProvision() - because the synchronizing group does not exist yet on Syncope</li>
-     * <li>beforeDelete() - because group delete cascades as membership removal for all users involved</li> </ul>
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta, final A any, final M anyPatch) throws JobExecutionException {
-
-        if (any instanceof GroupTO) {
-            // search for all users assigned to given group
-            Group group = groupDAO.find(any.getKey());
-            if (group != null) {
-                List<UMembership> membs = groupDAO.findUMemberships(group);
-                // save memberships before group update takes place
-                membersBeforeGroupUpdate = new HashMap<>(membs.size());
-                for (UMembership memb : membs) {
-                    membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
-                }
-            }
-        }
-
-        return super.beforeUpdate(profile, delta, any, anyPatch);
-    }
-
-    /**
-     * Build UserPatch for adding membership to given user, for given group.
-     *
-     * @param userKey user to be assigned membership to given group
-     * @param groupTO group for adding membership
-     * @return UserPatch for user update
-     */
-    protected UserPatch getUserPatch(final Long userKey, final GroupTO groupTO) {
-        UserPatch userPatch = new UserPatch();
-        // no actual modification takes place when user has already the group assigned
-        if (membersBeforeGroupUpdate.containsKey(userKey)) {
-            membersBeforeGroupUpdate.remove(userKey);
-        } else {
-            userPatch.setKey(userKey);
-
-            userPatch.getMemberships().add(
-                    new MembershipPatch.Builder().
-                    operation(PatchOperation.ADD_REPLACE).
-                    membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
-                    build());
-        }
-
-        return userPatch;
-    }
-
-    /**
-     * Read values of attribute returned by getGroupMembershipAttrName(); if not present in the given delta, perform an
-     * additional read on the underlying connector.
-     *
-     * @param delta representing the synchronizing group
-     * @param connector associated to the current resource
-     * @return value of attribute returned by
-     * {@link #getGroupMembershipAttrName}
-     */
-    protected List<Object> getMembAttrValues(final SyncDelta delta, final Connector connector) {
-        List<Object> result = Collections.<Object>emptyList();
-        String groupMemberName = getGroupMembershipAttrName(connector);
-
-        // first, try to read the configured attribute from delta, returned by the ongoing synchronization
-        Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
-        // if not found, perform an additional read on the underlying connector for the same connector object
-        if (membAttr == null) {
-            OperationOptionsBuilder oob = new OperationOptionsBuilder();
-            oob.setAttributesToGet(groupMemberName);
-            ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), oob.build());
-            if (remoteObj == null) {
-                LOG.debug("Object for '{}' not found", delta.getUid().getUidValue());
-            } else {
-                membAttr = remoteObj.getAttributeByName(groupMemberName);
-            }
-        }
-        if (membAttr != null && membAttr.getValue() != null) {
-            result = membAttr.getValue();
-        }
-
-        return result;
-    }
-
-    /**
-     * Perform actual modifications (i.e. membership add / remove) for the given group on the given resource.
-     *
-     * @param userPatch modifications to perform on the user
-     * @param resourceName resource to be propagated for changes
-     */
-    protected void userUpdate(final UserPatch userPatch, final String resourceName) {
-        if (userPatch.getKey() == 0) {
-            return;
-        }
-
-        Result result;
-
-        WorkflowResult<Pair<UserPatch, Boolean>> updated = null;
-
-        try {
-            updated = uwfAdapter.update(userPatch);
-
-            List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                    updated, false, Collections.singleton(resourceName));
-
-            taskExecutor.execute(tasks);
-            result = Result.SUCCESS;
-        } catch (PropagationException e) {
-            result = Result.FAILURE;
-            LOG.error("Could not propagate {}", userPatch, e);
-        } catch (Exception e) {
-            result = Result.FAILURE;
-            LOG.error("Could not perform update {}", userPatch, e);
-        }
-
-        notificationManager.createTasks(
-                AuditElements.EventCategoryType.SYNCHRONIZATION,
-                this.getClass().getSimpleName(),
-                null,
-                "update",
-                result,
-                null, // searching for before object is too much expensive ... 
-                updated == null ? null : updated.getResult().getKey(),
-                userPatch,
-                resourceName);
-
-        auditManager.audit(
-                AuditElements.EventCategoryType.SYNCHRONIZATION,
-                this.getClass().getSimpleName(),
-                null,
-                "update",
-                result,
-                null, // searching for before object is too much expensive ... 
-                updated == null ? null : updated.getResult().getKey(),
-                userPatch,
-                resourceName);
-    }
-
-    /**
-     * Synchronize Syncope memberships with the situation read on the external resource's group.
-     *
-     * @param profile sync profile
-     * @param delta representing the synchronizing group
-     * @param groupTO group after modification performed by the handler
-     * @throws JobExecutionException if anything goes wrong
-     */
-    protected void synchronizeMemberships(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
-            throws JobExecutionException {
-
-        ProvisioningTask task = profile.getTask();
-        ExternalResource resource = task.getResource();
-        Connector connector = profile.getConnector();
-
-        for (Object membValue : getMembAttrValues(delta, connector)) {
-            Long userKey = syncUtils.findMatchingAnyKey(
-                    anyTypeDAO.findUser(),
-                    membValue.toString(),
-                    profile.getTask().getResource(),
-                    profile.getConnector());
-            if (userKey != null) {
-                UserPatch userPatch = getUserPatch(userKey, groupTO);
-                userUpdate(userPatch, resource.getKey());
-            }
-        }
-
-        // finally remove any residual membership that was present before group update but not any more
-        for (Map.Entry<Long, Long> member : membersBeforeGroupUpdate.entrySet()) {
-            UserPatch userPatch = new UserPatch();
-            userPatch.setKey(member.getKey());
-
-            userPatch.getMemberships().add(
-                    new MembershipPatch.Builder().
-                    operation(PatchOperation.DELETE).
-                    membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
-                    build());
-
-            userUpdate(userPatch, resource.getKey());
-        }
-    }
-
-    /**
-     * Synchronize membership at group synchronization time (because SyncJob first synchronize users then groups).
-     * {@inheritDoc}
-     */
-    @Override
-    public <A extends AnyTO> void after(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final ProvisioningReport result) throws JobExecutionException {
-
-        if (!(profile.getTask() instanceof SyncTask)) {
-            return;
-        }
-
-        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) any);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
deleted file mode 100644
index 134c1f1..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-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.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.codec.Base64;
-import org.springframework.security.crypto.codec.Hex;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * A SyncActions implementation which allows the ability to import passwords from an LDAP backend
- * that are hashed.
- */
-public class LDAPPasswordSyncActions extends DefaultSyncActions {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(LDAPPasswordSyncActions.class);
-
-    @Autowired
-    private UserDAO userDAO;
-
-    private String encodedPassword;
-
-    private CipherAlgorithm cipher;
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any) throws JobExecutionException {
-
-        if (any instanceof UserTO) {
-            String password = ((UserTO) any).getPassword();
-            parseEncodedPassword(password);
-        }
-
-        return delta;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final M anyPatch) throws JobExecutionException {
-
-        if (anyPatch instanceof UserPatch) {
-            PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
-            parseEncodedPassword(modPassword == null ? null : modPassword.getValue());
-        }
-
-        return delta;
-    }
-
-    private void parseEncodedPassword(final String password) {
-        if (password != null && password.startsWith("{")) {
-            int closingBracketIndex = password.indexOf('}');
-            String digest = password.substring(1, password.indexOf('}'));
-            if (digest != null) {
-                digest = digest.toUpperCase();
-            }
-            try {
-                encodedPassword = password.substring(closingBracketIndex + 1);
-                cipher = CipherAlgorithm.valueOf(digest);
-            } catch (IllegalArgumentException e) {
-                LOG.error("Cipher algorithm not allowed: {}", digest, e);
-                encodedPassword = null;
-            }
-        }
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends AnyTO> void after(
-            final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta,
-            final A any,
-            final ProvisioningReport result) throws JobExecutionException {
-
-        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
-            User syncopeUser = userDAO.find(any.getKey());
-            if (syncopeUser != null) {
-                byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
-                char[] encodedHex = Hex.encode(encodedPasswordBytes);
-                String encodedHexStr = new String(encodedHex).toUpperCase();
-
-                syncopeUser.setEncodedPassword(encodedHexStr, cipher);
-            }
-            encodedPassword = null;
-            cipher = null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
deleted file mode 100644
index 343ba3f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-
-public class PlainAttrsSyncCorrelationRule implements SyncCorrelationRule {
-
-    private final List<String> plainSchemaNames;
-
-    private final Provision provision;
-
-    public PlainAttrsSyncCorrelationRule(final String[] plainSchemaNames, final Provision provision) {
-        this.plainSchemaNames = Arrays.asList(plainSchemaNames);
-        this.provision = provision;
-    }
-
-    @Override
-    public SearchCond getSearchCond(final ConnectorObject connObj) {
-        Map<String, MappingItem> mappingItems = new HashMap<>();
-        for (MappingItem item : MappingManagerImpl.getSyncMappingItems(provision)) {
-            mappingItems.put(item.getIntAttrName(), item);
-        }
-
-        // search for anys by attribute(s) specified in the policy
-        SearchCond searchCond = null;
-
-        for (String schema : plainSchemaNames) {
-            Attribute attr = mappingItems.get(schema) == null
-                    ? null
-                    : connObj.getAttributeByName(mappingItems.get(schema).getExtAttrName());
-            if (attr == null) {
-                throw new IllegalArgumentException(
-                        "Connector object does not contains the attributes to perform the search: " + schema);
-            }
-
-            List<Object> values = attr.getValue();
-            for (MappingItemTransformer transformer
-                    : MappingManagerImpl.getMappingItemTransformers(mappingItems.get(schema))) {
-
-                values = transformer.beforeSync(values);
-            }
-
-            AttributeCond.Type type;
-            String expression = null;
-
-            if (values == null || values.isEmpty() || (values.size() == 1 && values.get(0) == null)) {
-                type = AttributeCond.Type.ISNULL;
-            } else {
-                type = AttributeCond.Type.EQ;
-                expression = values.size() > 1
-                        ? values.toString()
-                        : values.get(0).toString();
-            }
-
-            SearchCond nodeCond;
-            // users: just key or username can be selected
-            // groups: just key or name can be selected
-            // any objects: just key can be selected
-            if ("key".equalsIgnoreCase(schema)
-                    || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
-
-                AnyCond cond = new AnyCond();
-                cond.setSchema(schema);
-                cond.setType(type);
-                cond.setExpression(expression);
-
-                nodeCond = SearchCond.getLeafCond(cond);
-            } else {
-                AttributeCond cond = new AttributeCond();
-                cond.setSchema(schema);
-                cond.setType(type);
-                cond.setExpression(expression);
-
-                nodeCond = SearchCond.getLeafCond(cond);
-            }
-
-            searchCond = searchCond == null
-                    ? nodeCond
-                    : SearchCond.getAndCond(searchCond, nodeCond);
-        }
-
-        return searchCond;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
deleted file mode 100644
index 4d44086..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectPushResultHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.GroupPushResultHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.UserPushResultHandler;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
-
-    private static final int PAGE_SIZE = 1000;
-
-    /**
-     * User DAO.
-     */
-    @Autowired
-    private UserDAO userDAO;
-
-    /**
-     * Search DAO.
-     */
-    @Autowired
-    private AnySearchDAO searchDAO;
-
-    /**
-     * Group DAO.
-     */
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
-        AnyDAO<?> result;
-        switch (anyTypeKind) {
-            case USER:
-                result = userDAO;
-                break;
-
-            case GROUP:
-                result = groupDAO;
-                break;
-
-            case ANY_OBJECT:
-            default:
-                result = anyObjectDAO;
-        }
-
-        return result;
-    }
-
-    protected void handle(
-            final List<? extends Any<?>> anys,
-            final SyncopePushResultHandler handler,
-            final ExternalResource resource)
-            throws JobExecutionException {
-
-        for (Any<?> any : anys) {
-            try {
-                handler.handle(any.getKey());
-            } catch (Exception e) {
-                LOG.warn("Failure pushing '{}' on '{}'", any, resource, e);
-                throw new JobExecutionException("While pushing " + any + " on " + resource, e);
-            }
-        }
-    }
-
-    @Override
-    protected String doExecuteProvisioning(
-            final PushTask pushTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing push on {}", pushTask.getResource());
-
-        List<PushActions> actions = new ArrayList<>();
-        for (String className : pushTask.getActionsClassNames()) {
-            try {
-                Class<?> actionsClass = Class.forName(className);
-
-                PushActions syncActions = (PushActions) ApplicationContextProvider.getBeanFactory().
-                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-                actions.add(syncActions);
-            } catch (Exception e) {
-                LOG.info("Class '{}' not found", className, e);
-            }
-        }
-
-        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
-        profile.setDryRun(dryRun);
-        profile.setResAct(null);
-
-        AnyObjectPushResultHandler ahandler =
-                (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        UserPushResultHandler uhandler =
-                (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        GroupPushResultHandler ghandler =
-                (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (!profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : pushTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
-
-                SyncopePushResultHandler handler;
-                switch (provision.getAnyType().getKind()) {
-                    case USER:
-                        handler = uhandler;
-                        break;
-
-                    case GROUP:
-                        handler = ghandler;
-                        break;
-
-                    case ANY_OBJECT:
-                    default:
-                        handler = ahandler;
-                }
-
-                String filter = pushTask.getFilter(provision.getAnyType()) == null
-                        ? null
-                        : pushTask.getFilter(provision.getAnyType()).getFIQLCond();
-                if (StringUtils.isBlank(filter)) {
-                    handle(anyDAO.findAll(), handler, pushTask.getResource());
-                } else {
-                    int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-                    for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
-                        List<? extends Any<?>> anys = searchDAO.search(
-                                SyncopeConstants.FULL_ADMIN_REALMS,
-                                SearchCondConverter.convert(filter),
-                                page,
-                                PAGE_SIZE,
-                                Collections.<OrderByClause>emptyList(),
-                                provision.getAnyType().getKind());
-                        handle(anys, handler, pushTask.getResource());
-                    }
-                }
-            }
-        }
-
-        if (!profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
-        LOG.debug("Sync result: {}", result);
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
deleted file mode 100644
index 78f253a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-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.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.GroupSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
-import org.apache.syncope.core.provisioning.api.syncpull.UserSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
-
-public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    protected SyncUtils syncUtils;
-
-    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
-        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
-            Group group = groupDAO.find(entry.getKey());
-            if (group == null) {
-                throw new NotFoundException("Group " + entry.getKey());
-            }
-
-            if (StringUtils.isBlank(entry.getValue())) {
-                group.setGroupOwner(null);
-                group.setUserOwner(null);
-            } else {
-                Long userKey = syncUtils.findMatchingAnyKey(
-                        anyTypeDAO.findUser(),
-                        entry.getValue(),
-                        ghandler.getProfile().getTask().getResource(),
-                        ghandler.getProfile().getConnector());
-
-                if (userKey == null) {
-                    Long groupKey = syncUtils.findMatchingAnyKey(
-                            anyTypeDAO.findGroup(),
-                            entry.getValue(),
-                            ghandler.getProfile().getTask().getResource(),
-                            ghandler.getProfile().getConnector());
-
-                    if (groupKey != null) {
-                        group.setGroupOwner(groupDAO.find(groupKey));
-                    }
-                } else {
-                    group.setUserOwner(userDAO.find(userKey));
-                }
-            }
-
-            groupDAO.save(group);
-        }
-    }
-
-    @Override
-    protected String doExecuteProvisioning(
-            final SyncTask syncTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing sync on {}", syncTask.getResource());
-
-        List<SyncActions> actions = new ArrayList<>();
-        for (String className : syncTask.getActionsClassNames()) {
-            try {
-                Class<?> actionsClass = Class.forName(className);
-                SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
-                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-
-                actions.add(syncActions);
-            } catch (Exception e) {
-                LOG.warn("Class '{}' not found", className, e);
-            }
-        }
-
-        ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
-        profile.getActions().addAll(actions);
-        profile.setDryRun(dryRun);
-        profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
-
-        // Prepare handler for SyncDelta objects (any objects)
-        AnyObjectSyncResultHandler ahandler = (AnyObjectSyncResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (users)
-        UserSyncResultHandler uhandler = (UserSyncResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (groups)
-        GroupSyncResultHandler ghandler = (GroupSyncResultHandler) ApplicationContextProvider.getBeanFactory().
-                createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (!profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : syncTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                SyncResultsHandler handler;
-                switch (provision.getAnyType().getKind()) {
-                    case USER:
-                        handler = uhandler;
-                        break;
-
-                    case GROUP:
-                        handler = ghandler;
-                        break;
-
-                    case ANY_OBJECT:
-                    default:
-                        handler = ahandler;
-                }
-
-                try {
-                    Set<MappingItem> linkinMappingItems = new HashSet<>();
-                    for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
-                        linkinMappingItems.add(virSchema.asLinkingMappingItem());
-                    }
-                    Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
-                            provision.getMapping().getItems().iterator(),
-                            linkinMappingItems.iterator());
-
-                    switch (syncTask.getSyncMode()) {
-                        case INCREMENTAL:
-                            SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
-                            connector.sync(provision.getObjectClass(),
-                                    provision.getSyncToken(),
-                                    handler,
-                                    MappingManagerImpl.buildOperationOptions(mapItems));
-                            if (!dryRun) {
-                                provision.setSyncToken(latestSyncToken);
-                                resourceDAO.save(provision.getResource());
-                            }
-                            break;
-
-                        case FILTERED_RECONCILIATION:
-                            ReconciliationFilterBuilder filterBuilder =
-                                    (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
-                                    createBean(Class.forName(syncTask.getReconciliationFilterBuilderClassName()),
-                                            AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-                            connector.filteredReconciliation(provision.getObjectClass(),
-                                    filterBuilder,
-                                    handler,
-                                    MappingManagerImpl.buildOperationOptions(mapItems));
-                            break;
-
-                        case FULL_RECONCILIATION:
-                        default:
-                            connector.fullReconciliation(provision.getObjectClass(),
-                                    handler,
-                                    MappingManagerImpl.buildOperationOptions(mapItems));
-                            break;
-                    }
-                } catch (Throwable t) {
-                    throw new JobExecutionException("While syncing from connector", t);
-                }
-            }
-        }
-
-        try {
-            setGroupOwners(ghandler);
-        } catch (Exception e) {
-            LOG.error("While setting group owners", e);
-        }
-
-        if (!profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
-
-        LOG.debug("Sync result: {}", result);
-
-        return result;
-    }
-
-    private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
-        SyncPolicySpec syncPolicySpec;
-
-        if (task instanceof SyncTask) {
-            syncPolicySpec = task.getResource().getSyncPolicy() == null
-                    ? null
-                    : task.getResource().getSyncPolicy().getSpecification();
-        } else {
-            syncPolicySpec = null;
-        }
-
-        // step required because the call <policy>.getSpecification() could return a null value
-        return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
deleted file mode 100644
index 9038b42..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-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.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeUtil;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(readOnly = true)
-@Component
-public class SyncUtils {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
-
-    /**
-     * Schema DAO.
-     */
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    /**
-     * Any Object DAO.
-     */
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    /**
-     * User DAO.
-     */
-    @Autowired
-    private UserDAO userDAO;
-
-    /**
-     * Group DAO.
-     */
-    @Autowired
-    private GroupDAO groupDAO;
-
-    /**
-     * Search DAO.
-     */
-    @Autowired
-    private AnySearchDAO searchDAO;
-
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
-    public Long findMatchingAnyKey(
-            final AnyType anyType,
-            final String name,
-            final ExternalResource resource,
-            final Connector connector) {
-
-        Provision provision = resource.getProvision(anyType);
-        if (provision == null) {
-            return null;
-        }
-
-        Long result = null;
-
-        AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind());
-
-        final List<ConnectorObject> found = new ArrayList<>();
-        connector.search(provision.getObjectClass(),
-                new EqualsFilter(new Name(name)),
-                new ResultsHandler() {
-
-            @Override
-            public boolean handle(final ConnectorObject obj) {
-                return found.add(obj);
-            }
-        },
-                MappingManagerImpl.buildOperationOptions(MappingManagerImpl.getSyncMappingItems(provision).iterator()));
-
-        if (found.isEmpty()) {
-            LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
-        } else {
-            if (found.size() > 1) {
-                LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
-                        provision.getObjectClass(), resource, name);
-            }
-
-            ConnectorObject connObj = found.iterator().next();
-            try {
-                List<Long> anyKeys = findExisting(connObj.getUid().getUidValue(), connObj, provision, anyUtils);
-                if (anyKeys.isEmpty()) {
-                    LOG.debug("No matching {} found for {}, aborting", anyUtils.getAnyTypeKind(), connObj);
-                } else {
-                    if (anyKeys.size() > 1) {
-                        LOG.warn("More than one {} found {} - taking first only", anyUtils.getAnyTypeKind(), anyKeys);
-                    }
-
-                    result = anyKeys.iterator().next();
-                }
-            } catch (IllegalArgumentException e) {
-                LOG.warn(e.getMessage());
-            }
-        }
-
-        return result;
-    }
-
-    private AnyDAO<?> getAnyDAO(final MappingItem connObjectKeyItem) {
-        return AnyTypeKind.USER == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
-                ? userDAO
-                : AnyTypeKind.ANY_OBJECT == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
-                        ? anyObjectDAO
-                        : groupDAO;
-    }
-
-    private List<Long> findByConnObjectKeyItem(
-            final String uid, final Provision provision, final AnyUtils anyUtils) {
-
-        List<Long> result = new ArrayList<>();
-
-        MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
-
-        String transfUid = uid;
-        for (MappingItemTransformer transformer : MappingManagerImpl.getMappingItemTransformers(connObjectKeyItem)) {
-            List<Object> output = transformer.beforeSync(Collections.<Object>singletonList(transfUid));
-            if (output != null && !output.isEmpty()) {
-                transfUid = output.get(0).toString();
-            }
-        }
-
-        switch (connObjectKeyItem.getIntMappingType()) {
-            case UserPlainSchema:
-            case GroupPlainSchema:
-            case AnyObjectPlainSchema:
-                PlainAttrValue value = anyUtils.newPlainAttrValue();
-
-                PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
-                if (schema == null) {
-                    value.setStringValue(transfUid);
-                } else {
-                    try {
-                        value.parseValue(schema, transfUid);
-                    } catch (ParsingValidationException e) {
-                        LOG.error("While parsing provided __UID__ {}", transfUid, e);
-                        value.setStringValue(transfUid);
-                    }
-                }
-
-                List<? extends Any<?>> anys =
-                        getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value);
-                for (Any<?> any : anys) {
-                    result.add(any.getKey());
-                }
-                break;
-
-            case UserDerivedSchema:
-            case GroupDerivedSchema:
-            case AnyObjectDerivedSchema:
-                anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), transfUid);
-                for (Any<?> any : anys) {
-                    result.add(any.getKey());
-                }
-                break;
-
-            case UserKey:
-            case GroupKey:
-            case AnyObjectKey:
-                Any<?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid));
-                if (any != null) {
-                    result.add(any.getKey());
-                }
-                break;
-
-            case Username:
-                User user = userDAO.find(transfUid);
-                if (user != null) {
-                    result.add(user.getKey());
-                }
-                break;
-
-            case GroupName:
-                Group group = groupDAO.find(transfUid);
-                if (group != null) {
-                    result.add(group.getKey());
-                }
-                break;
-
-            default:
-                LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
-        }
-
-        return result;
-    }
-
-    private List<Long> findByCorrelationRule(
-            final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
-
-        List<Long> result = new ArrayList<>();
-        for (Any<?> any : searchDAO.search(rule.getSearchCond(connObj), type)) {
-            result.add(any.getKey());
-        }
-
-        return result;
-    }
-
-    private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
-        SyncCorrelationRule result = null;
-
-        String syncCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
-        if (StringUtils.isNotBlank(syncCorrelationRule)) {
-            if (syncCorrelationRule.charAt(0) == '[') {
-                result = new PlainAttrsSyncCorrelationRule(
-                        POJOHelper.deserialize(syncCorrelationRule, String[].class), provision);
-            } else {
-                try {
-                    result = (SyncCorrelationRule) Class.forName(syncCorrelationRule).newInstance();
-                } catch (Exception e) {
-                    LOG.error("Failure instantiating correlation rule class '{}'", syncCorrelationRule, e);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Find any objects based on mapped uid value (or previous uid value, if updated).
-     *
-     * @param uid for finding by connObjectKey
-     * @param connObj for finding by attribute value
-     * @param provision external resource
-     * @param anyUtils any util
-     * @return list of matching users / groups
-     */
-    public List<Long> findExisting(
-            final String uid,
-            final ConnectorObject connObj,
-            final Provision provision,
-            final AnyUtils anyUtils) {
-
-        SyncPolicySpec syncPolicySpec = null;
-        if (provision.getResource().getSyncPolicy() != null) {
-            syncPolicySpec = provision.getResource().getSyncPolicy().getSpecification();
-        }
-
-        SyncCorrelationRule syncRule = null;
-        if (syncPolicySpec != null) {
-            syncRule = getCorrelationRule(provision, syncPolicySpec);
-        }
-
-        return syncRule == null
-                ? findByConnObjectKeyItem(uid, provision, anyUtils)
-                : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
-    }
-
-    public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
-        Boolean enabled = null;
-        if (task.isSyncStatus()) {
-            Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes());
-            if (status != null && status.getValue() != null && !status.getValue().isEmpty()) {
-                enabled = (Boolean) status.getValue().get(0);
-            }
-        }
-
-        return enabled;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
deleted file mode 100644
index a589416..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-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.user.User;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.UserPushResultHandler;
-
-public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
-    }
-
-    @Override
-    protected void provision(final Any<?> any, final Boolean enabled) {
-        AnyTO before = getAnyTO(any.getKey());
-
-        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.getUserCreateTasks(
-                before.getKey(),
-                null,
-                enabled,
-                propByRes,
-                before.getVirAttrs(),
-                noPropResources));
-    }
-
-    @Override
-    protected String getName(final Any<?> any) {
-        return User.class.cast(any).getUsername();
-    }
-
-    @Override
-    protected Any<?> getAny(final long key) {
-        try {
-            return userDAO.authFind(key);
-        } catch (Exception e) {
-            LOG.warn("Error retrieving user {}", key, e);
-            return null;
-        }
-    }
-
-    @Override
-    protected AnyTO getAnyTO(final long key) {
-        return userDataBinder.getUserTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        UserPatch patch = new UserPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
-        return new WorkflowResult<>(
-                update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
deleted file mode 100644
index 92dd5eb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.syncpull;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.syncpull.UserSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler implements UserSyncResultHandler {
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
-    }
-
-    @Override
-    protected String getName(final AnyTO anyTO) {
-        return UserTO.class.cast(anyTO).getUsername();
-    }
-
-    @Override
-    protected ProvisioningManager<?, ?> getProvisioningManager() {
-        return userProvisioningManager;
-    }
-
-    @Override
-    protected Any<?> getAny(final long key) {
-        try {
-            return userDAO.authFind(key);
-        } catch (Exception e) {
-            LOG.warn("Error retrieving user {}", key, e);
-            return null;
-        }
-    }
-
-    @Override
-    protected AnyTO getAnyTO(final long key) {
-        return userDataBinder.getUserTO(key);
-    }
-
-    @Override
-    protected AnyPatch newPatch(final long key) {
-        UserPatch patch = new UserPatch();
-        patch.setKey(key);
-        return patch;
-    }
-
-    @Override
-    protected WorkflowResult<Long> update(final AnyPatch patch) {
-        WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
-        return new WorkflowResult<>(
-                update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
-    }
-
-    @Override
-    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
-        UserTO userTO = UserTO.class.cast(anyTO);
-
-        Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
-        Map.Entry<Long, List<PropagationStatus>> created =
-                userProvisioningManager.create(userTO, true, true, enabled,
-                        Collections.singleton(profile.getTask().getResource().getKey()), true);
-
-        result.setKey(created.getKey());
-        result.setName(getName(anyTO));
-
-        return getAnyTO(created.getKey());
-    }
-
-    @Override
-    protected AnyTO doUpdate(
-            final AnyTO before,
-            final AnyPatch anyPatch,
-            final SyncDelta delta,
-            final ProvisioningReport result) {
-
-        UserPatch userPatch = UserPatch.class.cast(anyPatch);
-        Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
-
-        Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(
-                userPatch,
-                result,
-                enabled,
-                Collections.singleton(profile.getTask().getResource().getKey()),
-                true);
-
-        return getAnyTO(updated.getKey());
-    }
-
-    @Override
-    protected void doDelete(final AnyTypeKind kind, final Long key) {
-        try {
-            userProvisioningManager.delete(
-                    key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
-        } 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 " + key, e);
-        }
-
-        uwfAdapter.delete(key);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
index 703bc49..e5ae650 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -36,7 +36,6 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.spring.security.PasswordGenerator;
@@ -44,6 +43,7 @@ import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
 import org.identityconnectors.common.Base64;
@@ -120,7 +120,7 @@ public class ConnObjectUtils {
      * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
      *
      * @param obj connector object
-     * @param syncTask synchronization task
+     * @param pullTask pull task
      * @param provision provision information
      * @param anyUtils utils
      * @param <T> any object
@@ -128,9 +128,9 @@ public class ConnObjectUtils {
      */
     @Transactional(readOnly = true)
     public <T extends AnyTO> T getAnyTO(
-            final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+            final ConnectorObject obj, final PullTask pullTask, final Provision provision, final AnyUtils anyUtils) {
 
-        T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+        T anyTO = getAnyTOFromConnObject(obj, pullTask, provision, anyUtils);
 
         // (for users) if password was not set above, generate
         if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
@@ -174,7 +174,7 @@ public class ConnObjectUtils {
      * @param key any object to be updated
      * @param obj connector object
      * @param original any object to get diff from
-     * @param syncTask synchronization task
+     * @param pullTask pull task
      * @param provision provision information
      * @param anyUtils utils
      * @param <T> any object
@@ -183,9 +183,9 @@ public class ConnObjectUtils {
     @SuppressWarnings("unchecked")
     @Transactional(readOnly = true)
     public <T extends AnyPatch> T getAnyPatch(final Long key, final ConnectorObject obj,
-            final AnyTO original, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+            final AnyTO original, final PullTask pullTask, final Provision provision, final AnyUtils anyUtils) {
 
-        AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+        AnyTO updated = getAnyTOFromConnObject(obj, pullTask, provision, anyUtils);
         updated.setKey(key);
 
         if (null != anyUtils.getAnyTypeKind()) {
@@ -215,19 +215,19 @@ public class ConnObjectUtils {
     }
 
     private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
-            final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+            final PullTask pullTask, final Provision provision, final AnyUtils anyUtils) {
 
         T anyTO = anyUtils.newAnyTO();
         anyTO.setType(provision.getAnyType().getKey());
 
         // 1. fill with data from connector object
-        anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
-        for (MappingItem item : MappingManagerImpl.getSyncMappingItems(provision)) {
+        anyTO.setRealm(pullTask.getDestinatioRealm().getFullPath());
+        for (MappingItem item : MappingManagerImpl.getPullMappingItems(provision)) {
             mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
         }
 
         // 2. add data from defined template (if any)
-        templateUtils.apply(anyTO, syncTask.getTemplate(provision.getAnyType()));
+        templateUtils.apply(anyTO, pullTask.getTemplate(provision.getAnyType()));
 
         return anyTO;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
index 5e81978..2e7be27 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.SyncPolicyTO;
+import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.PolicyService;
@@ -73,8 +73,8 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
                 logic.update((PasswordPolicyTO) policyTO);
                 break;
 
-            case SYNC:
-                logic.update((SyncPolicyTO) policyTO);
+            case PULL:
+                logic.update((PullPolicyTO) policyTO);
                 break;
 
             default:

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 54d256f..b6a1cdf 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
-import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -51,7 +51,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     @Override
     public Response create(final SchedTaskTO taskTO) {
         SchedTaskTO createdTask;
-        if (taskTO instanceof SyncTaskTO || taskTO instanceof PushTaskTO || taskTO instanceof SchedTaskTO) {
+        if (taskTO instanceof PullTaskTO || taskTO instanceof PushTaskTO || taskTO instanceof SchedTaskTO) {
             createdTask = logic.createSchedTask(taskTO);
         } else {
             throw new BadRequestException();

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
index 7cdf9d1..0217f17 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
@@ -70,14 +70,14 @@ public class CamelGroupProvisioningManager
             final Set<String> excludedResources,
             final boolean nullPriorityAsync) {
 
-        PollingConsumer pollingConsumer = getConsumer("direct:createGroupInSyncPort");
+        PollingConsumer pollingConsumer = getConsumer("direct:createGroupInPullPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("groupOwnerMap", groupOwnerMap);
         props.put("excludedResources", excludedResources);
         props.put("nullPriorityAsync", nullPriorityAsync);
 
-        sendMessage("direct:createGroupInSync", groupTO, props);
+        sendMessage("direct:createGroupInPull", groupTO, props);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 2c1fe6d..9a9b1b0 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -36,7 +36,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -326,7 +326,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
             final Set<String> excludedResources,
             final boolean nullPriorityAsync) {
 
-        PollingConsumer pollingConsumer = getConsumer("direct:updateInSyncPort");
+        PollingConsumer pollingConsumer = getConsumer("direct:updateInPullPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("key", userPatch.getKey());
@@ -335,22 +335,22 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         props.put("excludedResources", excludedResources);
         props.put("nullPriorityAsync", nullPriorityAsync);
 
-        sendMessage("direct:updateUserInSync", userPatch, props);
+        sendMessage("direct:updateUserInPull", userPatch, props);
 
         Exchange exchange = pollingConsumer.receive();
 
         Exception ex = (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
         if (ex != null) {
-            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)",
+            LOG.error("Update of user {} failed, trying to pull its status anyway (if configured)",
                     nullPriorityAsync, ex);
 
             result.setStatus(ProvisioningReport.Status.FAILURE);
-            result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + ex.getMessage());
+            result.setMessage("Update failed, trying to pull status anyway (if configured)\n" + ex.getMessage());
 
             WorkflowResult<Pair<UserPatch, Boolean>> updated = new WorkflowResult<Pair<UserPatch, Boolean>>(
                     new ImmutablePair<>(userPatch, false), new PropagationByResource(),
                     new HashSet<String>());
-            sendMessage("direct:userInSync", updated, props);
+            sendMessage("direct:userInPull", updated, props);
             exchange = pollingConsumer.receive();
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInPullProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInPullProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInPullProcessor.java
new file mode 100644
index 0000000..791b4b3
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInPullProcessor.java
@@ -0,0 +1,76 @@
+package org.apache.syncope.core.provisioning.camel.processor;
+
+/*
+ * 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.
+ */
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GroupCreateInPullProcessor implements Processor {
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+
+        GroupTO groupTO = exchange.getProperty("any", GroupTO.class);
+        Map<Long, String> groupOwnerMap = exchange.getProperty("groupOwnerMap", Map.class);
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+        Boolean nullPriorityAsync = exchange.getProperty("nullPriorityAsync", Boolean.class);
+
+        AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
+        if (groupOwner != null) {
+            groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
+        }
+
+        List<PropagationTask> tasks = propagationManager.getCreateTasks(
+                AnyTypeKind.GROUP,
+                created.getResult(),
+                created.getPropByRes(),
+                groupTO.getVirAttrs(),
+                excludedResources);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        taskExecutor.execute(tasks, propagationReporter, nullPriorityAsync);
+
+        exchange.getOut().setBody(new ImmutablePair<>(created.getResult(), null));
+    }
+}


[07/13] syncope git commit: [SYNCOPE-771] Rename completed

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
new file mode 100644
index 0000000..e2570eb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java
@@ -0,0 +1,434 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.pushpull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+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.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
+        implements SyncopePushResultHandler {
+
+    @Autowired
+    protected MappingManager mappingManager;
+
+    protected abstract String getName(Any<?> any);
+
+    protected void deprovision(final Any<?> any) {
+        AnyTO before = getAnyTO(any.getKey());
+
+        List<String> noPropResources = new ArrayList<>(before.getResources());
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getDeleteTasks(
+                any.getType().getKind(),
+                any.getKey(),
+                null,
+                noPropResources));
+    }
+
+    protected void provision(final Any<?> any, final Boolean enabled) {
+        AnyTO before = getAnyTO(any.getKey());
+
+        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.getCreateTasks(
+                any.getType().getKind(),
+                any.getKey(),
+                propByRes,
+                before.getVirAttrs(),
+                noPropResources));
+    }
+
+    @SuppressWarnings("unchecked")
+    protected void link(final Any<?> any, final Boolean unlink) {
+        AnyPatch patch = newPatch(any.getKey());
+        patch.getResources().add(new StringPatchItem.Builder().
+                operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
+                value(profile.getTask().getResource().getKey()).build());
+
+        update(patch);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected void unassign(final Any<?> any) {
+        AnyPatch patch = newPatch(any.getKey());
+        patch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.DELETE).
+                value(profile.getTask().getResource().getKey()).build());
+
+        update(patch);
+
+        deprovision(any);
+    }
+
+    protected void assign(final Any<?> any, final Boolean enabled) {
+        AnyPatch patch = newPatch(any.getKey());
+        patch.getResources().add(new StringPatchItem.Builder().
+                operation(PatchOperation.ADD_REPLACE).
+                value(profile.getTask().getResource().getKey()).build());
+
+        update(patch);
+
+        provision(any, enabled);
+    }
+
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+        ConnectorObject obj = null;
+        try {
+            Uid uid = new Uid(connObjectKey);
+
+            obj = profile.getConnector().getObject(objectClass,
+                    uid,
+                    MappingManagerImpl.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
+        } catch (TimeoutException toe) {
+            LOG.debug("Request timeout", toe);
+            throw toe;
+        } catch (RuntimeException ignore) {
+            LOG.debug("While resolving {}", connObjectKey, ignore);
+        }
+
+        return obj;
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW)
+    @Override
+    public boolean handle(final long anyKey) {
+        Any<?> any = null;
+        try {
+            any = getAny(anyKey);
+            doHandle(any);
+            return true;
+        } catch (IgnoreProvisionException e) {
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.NONE);
+            result.setAnyType(any == null ? null : any.getType().getKey());
+            result.setStatus(ProvisioningReport.Status.IGNORE);
+            result.setKey(anyKey);
+            profile.getResults().add(result);
+
+            LOG.warn("Ignoring during push", e);
+            return true;
+        } catch (JobExecutionException e) {
+            LOG.error("Push failed", e);
+            return false;
+        }
+    }
+
+    protected final void doHandle(final Any<?> any) throws JobExecutionException {
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+
+        ProvisioningReport result = new ProvisioningReport();
+        profile.getResults().add(result);
+
+        result.setKey(any.getKey());
+        result.setAnyType(any.getType().getKey());
+        result.setName(getName(any));
+
+        Boolean enabled = any instanceof User && profile.getTask().isPullStatus()
+                ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+                : null;
+
+        LOG.debug("Propagating {} with key {} towards {}",
+                anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
+
+        Object output = null;
+        Result resultStatus = null;
+        String operation = null;
+
+        // Try to read remote object BEFORE any actual operation
+        Provision provision = profile.getTask().getResource().getProvision(any.getType());
+        String connObjecKey = mappingManager.getConnObjectKeyValue(any, provision);
+
+        ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
+
+        Boolean status = profile.getTask().isPullStatus() ? enabled : null;
+
+        if (profile.isDryRun()) {
+            if (beforeObj == null) {
+                result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+            } else {
+                result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+            }
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+        } else {
+            try {
+                if (beforeObj == null) {
+                    operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
+                    result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+
+                    switch (profile.getTask().getUnmatchingRule()) {
+                        case ASSIGN:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeAssign(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformCreate()) {
+                                LOG.debug("PushTask not configured for create");
+                            } else {
+                                assign(any, status);
+                            }
+
+                            break;
+
+                        case PROVISION:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeProvision(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformCreate()) {
+                                LOG.debug("PushTask not configured for create");
+                            } else {
+                                provision(any, status);
+                            }
+
+                            break;
+
+                        case UNLINK:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeUnlink(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(any, true);
+                            }
+
+                            break;
+
+                        case IGNORE:
+                            LOG.debug("Ignored any: {}", any);
+                            break;
+                        default:
+                        // do nothing
+                    }
+                } else {
+                    operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
+                    result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+
+                    switch (profile.getTask().getMatchingRule()) {
+                        case UPDATE:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeUpdate(this.getProfile(), any);
+                            }
+                            if (!profile.getTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                update(any, status);
+                            }
+
+                            break;
+
+                        case DEPROVISION:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeDeprovision(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformDelete()) {
+                                LOG.debug("PushTask not configured for delete");
+                            } else {
+                                deprovision(any);
+                            }
+
+                            break;
+
+                        case UNASSIGN:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeUnassign(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformDelete()) {
+                                LOG.debug("PushTask not configured for delete");
+                            } else {
+                                unassign(any);
+                            }
+
+                            break;
+
+                        case LINK:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeLink(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(any, false);
+                            }
+
+                            break;
+
+                        case UNLINK:
+                            for (PushActions action : profile.getActions()) {
+                                action.beforeUnlink(this.getProfile(), any);
+                            }
+
+                            if (!profile.getTask().isPerformUpdate()) {
+                                LOG.debug("PushTask not configured for update");
+                            } else {
+                                link(any, true);
+                            }
+
+                            break;
+
+                        case IGNORE:
+                            LOG.debug("Ignored any: {}", any);
+                            break;
+                        default:
+                        // do nothing
+                    }
+                }
+
+                for (PushActions action : profile.getActions()) {
+                    action.after(this.getProfile(), any, result);
+                }
+
+                result.setStatus(ProvisioningReport.Status.SUCCESS);
+                resultStatus = AuditElements.Result.SUCCESS;
+                output = getRemoteObject(connObjecKey, provision.getObjectClass());
+            } catch (IgnoreProvisionException e) {
+                throw e;
+            } catch (Exception e) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                resultStatus = AuditElements.Result.FAILURE;
+                output = e;
+
+                LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
+
+                for (PushActions action : profile.getActions()) {
+                    action.onError(this.getProfile(), any, result, e);
+                }
+
+                throw new JobExecutionException(e);
+            } finally {
+                notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
+                        any.getType().getKind().name().toLowerCase(),
+                        profile.getTask().getResource().getKey(),
+                        operation,
+                        resultStatus,
+                        beforeObj,
+                        output,
+                        any);
+                auditManager.audit(AuditElements.EventCategoryType.PUSH,
+                        any.getType().getKind().name().toLowerCase(),
+                        profile.getTask().getResource().getKey(),
+                        operation,
+                        resultStatus,
+                        connObjectUtils.getConnObjectTO(beforeObj),
+                        output instanceof ConnectorObject
+                                ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
+                        any);
+            }
+        }
+    }
+
+    private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+        switch (rule) {
+            case ASSIGN:
+            case PROVISION:
+                return ResourceOperation.CREATE;
+            default:
+                return ResourceOperation.NONE;
+        }
+    }
+
+    private ResourceOperation getResourceOperation(final MatchingRule rule) {
+        switch (rule) {
+            case UPDATE:
+                return ResourceOperation.UPDATE;
+            case DEPROVISION:
+            case UNASSIGN:
+                return ResourceOperation.DELETE;
+            default:
+                return ResourceOperation.NONE;
+        }
+    }
+
+    protected Any<?> update(final Any<?> any, final Boolean enabled) {
+        boolean changepwd;
+        Collection<String> resourceNames;
+        if (any instanceof User) {
+            changepwd = true;
+            resourceNames = userDAO.findAllResourceNames((User) any);
+        } else if (any instanceof AnyObject) {
+            changepwd = false;
+            resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
+        } else {
+            changepwd = false;
+            resourceNames = ((Group) any).getResourceNames();
+        }
+
+        List<String> noPropResources = new ArrayList<>(resourceNames);
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getUpdateTasks(
+                any.getType().getKind(),
+                any.getKey(),
+                changepwd,
+                null,
+                propByRes,
+                null,
+                noPropResources));
+
+        return getAny(any.getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
new file mode 100644
index 0000000..37f67ff
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
@@ -0,0 +1,155 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+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.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.SyncopeResultHandler;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningActions;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
+        implements SyncopeResultHandler<T, A> {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    /**
+     * ConnectorObject utils.
+     */
+    @Autowired
+    protected ConnObjectUtils connObjectUtils;
+
+    /**
+     * Notification Manager.
+     */
+    @Autowired
+    protected NotificationManager notificationManager;
+
+    /**
+     * Audit Manager.
+     */
+    @Autowired
+    protected AuditManager auditManager;
+
+    /**
+     * Propagation manager.
+     */
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    /**
+     * Task executor.
+     */
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    protected AnyObjectWorkflowAdapter awfAdapter;
+
+    /**
+     * User workflow adapter.
+     */
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+
+    /**
+     * Group workflow adapter.
+     */
+    @Autowired
+    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 AnyUtilsFactory anyUtilsFactory;
+
+    /**
+     * Sync profile.
+     */
+    protected ProvisioningProfile<T, A> profile;
+
+    protected abstract AnyUtils getAnyUtils();
+
+    protected abstract AnyTO getAnyTO(long key);
+
+    protected abstract Any<?> getAny(long key);
+
+    protected abstract AnyPatch newPatch(final long key);
+
+    protected abstract WorkflowResult<Long> update(AnyPatch patch);
+
+    @Override
+    public void setProfile(final ProvisioningProfile<T, A> profile) {
+        this.profile = profile;
+    }
+
+    @Override
+    public ProvisioningProfile<T, A> getProfile() {
+        return profile;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
new file mode 100644
index 0000000..67c5731
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPullResultHandlerImpl.java
@@ -0,0 +1,112 @@
+/*
+ * 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.pushpull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+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.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler;
+
+public class AnyObjectPullResultHandlerImpl extends AbstractPullResultHandler implements AnyObjectPullResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+    }
+
+    @Override
+    protected String getName(final AnyTO anyTO) {
+        return StringUtils.EMPTY;
+    }
+
+    @Override
+    protected ProvisioningManager<?, ?> getProvisioningManager() {
+        return anyObjectProvisioningManager;
+    }
+
+    @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 AnyTO getAnyTO(final long key) {
+        return anyObjectDataBinder.getAnyObjectTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        AnyObjectPatch patch = new AnyObjectPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        return awfAdapter.update((AnyObjectPatch) patch);
+    }
+
+    @Override
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+        AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+        Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+                anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+        result.setKey(created.getKey());
+        result.setName(getName(anyTO));
+
+        return getAnyTO(created.getKey());
+    }
+
+    @Override
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyPatch anyPatch,
+            final SyncDelta delta,
+            final ProvisioningReport result) {
+
+        AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
+
+        Map.Entry<Long, List<PropagationStatus>> updated =
+                anyObjectProvisioningManager.update(anyObjectPatch, true);
+
+        AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
+        result.setName(getName(after));
+        return after;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
new file mode 100644
index 0000000..ce5aebb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AnyObjectPushResultHandlerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.pushpull;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler;
+
+public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+    }
+
+    @Override
+    protected String getName(final Any<?> any) {
+        return StringUtils.EMPTY;
+    }
+
+    @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 AnyTO getAnyTO(final long key) {
+        return anyObjectDataBinder.getAnyObjectTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        AnyObjectPatch patch = new AnyObjectPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        return awfAdapter.update((AnyObjectPatch) patch);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
new file mode 100644
index 0000000..2df5ace
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
@@ -0,0 +1,142 @@
+/*
+ * 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.pushpull;
+
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+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;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * A {@link org.apache.syncope.core.provisioning.api.pushpull.PullActions} implementation which allows the ability to
+ * import passwords from a Database backend, where the passwords are hashed according to the password cipher algorithm
+ * property of the (DB) Connector and HEX-encoded.
+ */
+public class DBPasswordPullActions extends DefaultPullActions {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DBPasswordPullActions.class);
+
+    private static final String CLEARTEXT = "CLEARTEXT";
+
+    @Autowired
+    private UserDAO userDAO;
+
+    private String encodedPassword;
+
+    private CipherAlgorithm cipher;
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any) throws JobExecutionException {
+
+        if (any instanceof UserTO) {
+            String password = ((UserTO) any).getPassword();
+            parseEncodedPassword(password, profile.getConnector());
+        }
+
+        return delta;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final M anyPatch) throws JobExecutionException {
+
+        if (anyPatch instanceof UserPatch) {
+            PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
+            parseEncodedPassword(modPassword == null ? null : modPassword.getValue(), profile.getConnector());
+        }
+
+        return delta;
+    }
+
+    private void parseEncodedPassword(final String password, final Connector connector) {
+        if (password != null) {
+            ConnInstance connInstance = connector.getConnInstance();
+
+            String cipherAlgorithm = getCipherAlgorithm(connInstance);
+            if (!CLEARTEXT.equals(cipherAlgorithm)) {
+                try {
+                    encodedPassword = password;
+                    cipher = CipherAlgorithm.valueOf(cipherAlgorithm);
+                } catch (IllegalArgumentException e) {
+                    LOG.error("Cipher algorithm not allowed: {}", cipherAlgorithm, e);
+                    encodedPassword = null;
+                }
+            }
+        }
+    }
+
+    private String getCipherAlgorithm(final ConnInstance connInstance) {
+        ConnConfProperty cipherAlgorithm =
+                IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
+
+                    @Override
+                    public boolean evaluate(final ConnConfProperty property) {
+                        return "cipherAlgorithm".equals(property.getSchema().getName())
+                                && property.getValues() != null && !property.getValues().isEmpty();
+                    }
+                });
+
+        return cipherAlgorithm == null
+                ? CLEARTEXT
+                : (String) cipherAlgorithm.getValues().get(0);
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final ProvisioningReport result) throws JobExecutionException {
+
+        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+            User syncopeUser = userDAO.find(any.getKey());
+            if (syncopeUser != null) {
+                syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
+            }
+            encodedPassword = null;
+            cipher = null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
new file mode 100644
index 0000000..7a4cbe0
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
@@ -0,0 +1,121 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+
+/**
+ * Default (empty) implementation of {@link PullActions}.
+ */
+public abstract class DefaultPullActions implements PullActions {
+
+    @Override
+    public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
+    }
+
+    @Override
+    public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final P anyMod) throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeDelete(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeAssign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeLink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeUnassign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeDeprovision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeUnlink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+            throws JobExecutionException {
+
+        return delta;
+    }
+
+    @Override
+    public void onError(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final ProvisioningReport result,
+            final Exception error) throws JobExecutionException {
+    }
+
+    @Override
+    public <A extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any,
+            final ProvisioningReport result)
+            throws JobExecutionException {
+    }
+
+    @Override
+    public void afterAll(final ProvisioningProfile<?, ?> profile)
+            throws JobExecutionException {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushActions.java
new file mode 100644
index 0000000..2e75870
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushActions.java
@@ -0,0 +1,100 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.quartz.JobExecutionException;
+
+/**
+ * Default (empty) implementation of PushActions.
+ */
+public abstract class DefaultPushActions implements PushActions {
+
+    @Override
+    public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any)
+            throws JobExecutionException {
+
+        return any;
+    }
+
+    @Override
+    public <A extends Any<?>> void onError(
+            final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result,
+            final Exception error) throws JobExecutionException {
+
+        // do nothing
+    }
+
+    @Override
+    public <A extends Any<?>> void after(
+            final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result)
+            throws JobExecutionException {
+
+        // do nothing
+    }
+
+    @Override
+    public void afterAll(final ProvisioningProfile<?, ?> profile)
+            throws JobExecutionException {
+
+        // do nothing
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultReconciliationFilterBuilder.java
new file mode 100644
index 0000000..c46c0fb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultReconciliationFilterBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.pushpull;
+
+import static org.identityconnectors.framework.impl.api.local.operations.FilteredResultsHandler.PassThroughFilter;
+
+import org.identityconnectors.framework.common.objects.filter.Filter;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
+
+/**
+ * Default (pass-through) implementation of {@link ReconciliationFilterBuilder}.
+ */
+public abstract class DefaultReconciliationFilterBuilder implements ReconciliationFilterBuilder {
+
+    private static final PassThroughFilter PASS_THROUGH = new PassThroughFilter();
+
+    @Override
+    public Filter build() {
+        return PASS_THROUGH;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
new file mode 100644
index 0000000..b880b57
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPullResultHandlerImpl.java
@@ -0,0 +1,138 @@
+/*
+ * 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.pushpull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+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.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
+
+public class GroupPullResultHandlerImpl extends AbstractPullResultHandler implements GroupPullResultHandler {
+
+    protected final Map<Long, String> groupOwnerMap = new HashMap<>();
+
+    @Override
+    public Map<Long, String> getGroupOwnerMap() {
+        return this.groupOwnerMap;
+    }
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+    }
+
+    @Override
+    protected String getName(final AnyTO anyTO) {
+        return GroupTO.class.cast(anyTO).getName();
+    }
+
+    @Override
+    protected ProvisioningManager<?, ?> getProvisioningManager() {
+        return groupProvisioningManager;
+    }
+
+    @Override
+    protected Any<?> getAny(final long key) {
+        try {
+            return groupDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving group {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        return groupDataBinder.getGroupTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        GroupPatch patch = new GroupPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        return gwfAdapter.update((GroupPatch) patch);
+    }
+
+    @Override
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+        GroupTO groupTO = GroupTO.class.cast(anyTO);
+
+        Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(
+                groupTO,
+                groupOwnerMap,
+                Collections.singleton(profile.getTask().getResource().getKey()),
+                true);
+
+        result.setKey(created.getKey());
+        result.setName(getName(anyTO));
+
+        return getAnyTO(created.getKey());
+    }
+
+    @Override
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyPatch anyPatch,
+            final SyncDelta delta,
+            final ProvisioningReport result) {
+
+        GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
+
+        Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupPatch, true);
+
+        String groupOwner = null;
+        for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
+            if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
+                    && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
+
+                groupOwner = attrPatch.getAttrTO().getValues().get(0);
+            }
+        }
+        if (groupOwner != null) {
+            groupOwnerMap.put(updated.getKey(), groupOwner);
+        }
+
+        GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
+
+        result.setName(getName(after));
+
+        return after;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
new file mode 100644
index 0000000..c572177
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/GroupPushResultHandlerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.pushpull;
+
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+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.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler;
+
+public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+    }
+
+    @Override
+    protected String getName(final Any<?> any) {
+        return Group.class.cast(any).getName();
+    }
+
+    @Override
+    protected Any<?> getAny(final long key) {
+        try {
+            return groupDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving group {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        return groupDataBinder.getGroupTO(key);
+    }
+
+    @Override
+    protected AnyPatch newPatch(final long key) {
+        GroupPatch patch = new GroupPatch();
+        patch.setKey(key);
+        return patch;
+    }
+
+    @Override
+    protected WorkflowResult<Long> update(final AnyPatch patch) {
+        return gwfAdapter.update((GroupPatch) patch);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java
new file mode 100644
index 0000000..7f7971c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java
@@ -0,0 +1,333 @@
+/*
+ * 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.pushpull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+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.common.lib.types.PatchOperation;
+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;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+
+/**
+ * Simple action for pulling LDAP groups memberships to Syncope group memberships, when the same resource is
+ * configured for both users and groups.
+ *
+ * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
+ */
+public class LDAPMembershipPullActions extends DefaultPullActions {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipPullActions.class);
+
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @Autowired
+    protected UserWorkflowAdapter uwfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    private PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    @Autowired
+    private AuditManager auditManager;
+
+    @Autowired
+    private PullUtils pullUtils;
+
+    protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
+
+    /**
+     * Allows easy subclassing for the ConnId AD connector bundle.
+     *
+     * @param connector A Connector instance to query for the groupMemberAttribute property name
+     * @return the name of the attribute used to keep track of group memberships
+     */
+    protected String getGroupMembershipAttrName(final Connector connector) {
+        ConnConfProperty groupMembership = IterableUtils.find(connector.getConnInstance().getConf(),
+                new Predicate<ConnConfProperty>() {
+
+            @Override
+            public boolean evaluate(final ConnConfProperty property) {
+                return "groupMemberAttribute".equals(property.getSchema().getName())
+                        && property.getValues() != null && !property.getValues().isEmpty();
+            }
+        });
+
+        return groupMembership == null
+                ? "uniquemember"
+                : (String) groupMembership.getValues().get(0);
+    }
+
+    /**
+     * Keep track of members of the group being updated <b>before</b> actual update takes place. This is not needed on
+     * <ul> <li>beforeProvision() - because the pulling group does not exist yet on Syncope</li>
+     * <li>beforeDelete() - because group delete cascades as membership removal for all users involved</li> </ul>
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta, final A any, final M anyPatch) throws JobExecutionException {
+
+        if (any instanceof GroupTO) {
+            // search for all users assigned to given group
+            Group group = groupDAO.find(any.getKey());
+            if (group != null) {
+                List<UMembership> membs = groupDAO.findUMemberships(group);
+                // save memberships before group update takes place
+                membersBeforeGroupUpdate = new HashMap<>(membs.size());
+                for (UMembership memb : membs) {
+                    membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
+                }
+            }
+        }
+
+        return super.beforeUpdate(profile, delta, any, anyPatch);
+    }
+
+    /**
+     * Build UserPatch for adding membership to given user, for given group.
+     *
+     * @param userKey user to be assigned membership to given group
+     * @param groupTO group for adding membership
+     * @return UserPatch for user update
+     */
+    protected UserPatch getUserPatch(final Long userKey, final GroupTO groupTO) {
+        UserPatch userPatch = new UserPatch();
+        // no actual modification takes place when user has already the group assigned
+        if (membersBeforeGroupUpdate.containsKey(userKey)) {
+            membersBeforeGroupUpdate.remove(userKey);
+        } else {
+            userPatch.setKey(userKey);
+
+            userPatch.getMemberships().add(
+                    new MembershipPatch.Builder().
+                    operation(PatchOperation.ADD_REPLACE).
+                    membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
+                    build());
+        }
+
+        return userPatch;
+    }
+
+    /**
+     * Read values of attribute returned by getGroupMembershipAttrName(); if not present in the given delta, perform an
+     * additional read on the underlying connector.
+     *
+     * @param delta representing the pulling group
+     * @param connector associated to the current resource
+     * @return value of attribute returned by
+     * {@link #getGroupMembershipAttrName}
+     */
+    protected List<Object> getMembAttrValues(final SyncDelta delta, final Connector connector) {
+        List<Object> result = Collections.<Object>emptyList();
+        String groupMemberName = getGroupMembershipAttrName(connector);
+
+        // first, try to read the configured attribute from delta, returned by the ongoing pull
+        Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
+        // if not found, perform an additional read on the underlying connector for the same connector object
+        if (membAttr == null) {
+            OperationOptionsBuilder oob = new OperationOptionsBuilder();
+            oob.setAttributesToGet(groupMemberName);
+            ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), oob.build());
+            if (remoteObj == null) {
+                LOG.debug("Object for '{}' not found", delta.getUid().getUidValue());
+            } else {
+                membAttr = remoteObj.getAttributeByName(groupMemberName);
+            }
+        }
+        if (membAttr != null && membAttr.getValue() != null) {
+            result = membAttr.getValue();
+        }
+
+        return result;
+    }
+
+    /**
+     * Perform actual modifications (i.e. membership add / remove) for the given group on the given resource.
+     *
+     * @param userPatch modifications to perform on the user
+     * @param resourceName resource to be propagated for changes
+     */
+    protected void userUpdate(final UserPatch userPatch, final String resourceName) {
+        if (userPatch.getKey() == 0) {
+            return;
+        }
+
+        Result result;
+
+        WorkflowResult<Pair<UserPatch, Boolean>> updated = null;
+
+        try {
+            updated = uwfAdapter.update(userPatch);
+
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+                    updated, false, Collections.singleton(resourceName));
+
+            taskExecutor.execute(tasks);
+            result = Result.SUCCESS;
+        } catch (PropagationException e) {
+            result = Result.FAILURE;
+            LOG.error("Could not propagate {}", userPatch, e);
+        } catch (Exception e) {
+            result = Result.FAILURE;
+            LOG.error("Could not perform update {}", userPatch, e);
+        }
+
+        notificationManager.createTasks(AuditElements.EventCategoryType.PULL,
+                this.getClass().getSimpleName(),
+                null,
+                "update",
+                result,
+                null, // searching for before object is too much expensive ... 
+                updated == null ? null : updated.getResult().getKey(),
+                userPatch,
+                resourceName);
+
+        auditManager.audit(AuditElements.EventCategoryType.PULL,
+                this.getClass().getSimpleName(),
+                null,
+                "update",
+                result,
+                null, // searching for before object is too much expensive ... 
+                updated == null ? null : updated.getResult().getKey(),
+                userPatch,
+                resourceName);
+    }
+
+    /**
+     * Pull Syncope memberships with the situation read on the external resource's group.
+     *
+     * @param profile pull profile
+     * @param delta representing the pullong group
+     * @param groupTO group after modification performed by the handler
+     * @throws JobExecutionException if anything goes wrong
+     */
+    protected void pullMemberships(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
+            throws JobExecutionException {
+
+        ProvisioningTask task = profile.getTask();
+        ExternalResource resource = task.getResource();
+        Connector connector = profile.getConnector();
+
+        for (Object membValue : getMembAttrValues(delta, connector)) {
+            Long userKey = pullUtils.findMatchingAnyKey(
+                    anyTypeDAO.findUser(),
+                    membValue.toString(),
+                    profile.getTask().getResource(),
+                    profile.getConnector());
+            if (userKey != null) {
+                UserPatch userPatch = getUserPatch(userKey, groupTO);
+                userUpdate(userPatch, resource.getKey());
+            }
+        }
+
+        // finally remove any residual membership that was present before group update but not any more
+        for (Map.Entry<Long, Long> member : membersBeforeGroupUpdate.entrySet()) {
+            UserPatch userPatch = new UserPatch();
+            userPatch.setKey(member.getKey());
+
+            userPatch.getMemberships().add(
+                    new MembershipPatch.Builder().
+                    operation(PatchOperation.DELETE).
+                    membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
+                    build());
+
+            userUpdate(userPatch, resource.getKey());
+        }
+    }
+
+    /**
+     * Pull membership at group pull time (because PullJob first pulls users then groups).
+     * {@inheritDoc}
+     */
+    @Override
+    public <A extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final ProvisioningReport result) throws JobExecutionException {
+
+        if (!(profile.getTask() instanceof PullTask)) {
+            return;
+        }
+
+        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 {
+            pullMemberships(profile, delta, (GroupTO) any);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
new file mode 100644
index 0000000..2d61396
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
@@ -0,0 +1,124 @@
+/*
+ * 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.pushpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+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.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.codec.Base64;
+import org.springframework.security.crypto.codec.Hex;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * A {@link org.apache.syncope.core.provisioning.api.pushpull.PullActions} implementation which allows the ability to 
+ * import passwords from an LDAP backend that are hashed.
+ */
+public class LDAPPasswordPullActions extends DefaultPullActions {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(LDAPPasswordPullActions.class);
+
+    @Autowired
+    private UserDAO userDAO;
+
+    private String encodedPassword;
+
+    private CipherAlgorithm cipher;
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any) throws JobExecutionException {
+
+        if (any instanceof UserTO) {
+            String password = ((UserTO) any).getPassword();
+            parseEncodedPassword(password);
+        }
+
+        return delta;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final M anyPatch) throws JobExecutionException {
+
+        if (anyPatch instanceof UserPatch) {
+            PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
+            parseEncodedPassword(modPassword == null ? null : modPassword.getValue());
+        }
+
+        return delta;
+    }
+
+    private void parseEncodedPassword(final String password) {
+        if (password != null && password.startsWith("{")) {
+            int closingBracketIndex = password.indexOf('}');
+            String digest = password.substring(1, password.indexOf('}'));
+            if (digest != null) {
+                digest = digest.toUpperCase();
+            }
+            try {
+                encodedPassword = password.substring(closingBracketIndex + 1);
+                cipher = CipherAlgorithm.valueOf(digest);
+            } catch (IllegalArgumentException e) {
+                LOG.error("Cipher algorithm not allowed: {}", digest, e);
+                encodedPassword = null;
+            }
+        }
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public <A extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any,
+            final ProvisioningReport result) throws JobExecutionException {
+
+        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+            User syncopeUser = userDAO.find(any.getKey());
+            if (syncopeUser != null) {
+                byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
+                char[] encodedHex = Hex.encode(encodedPasswordBytes);
+                String encodedHexStr = new String(encodedHex).toUpperCase();
+
+                syncopeUser.setEncodedPassword(encodedHexStr, cipher);
+            }
+            encodedPassword = null;
+            cipher = null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/61a7fdd3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
new file mode 100644
index 0000000..d752cd5
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
@@ -0,0 +1,115 @@
+/*
+ * 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.pushpull;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+
+public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
+
+    private final List<String> plainSchemaNames;
+
+    private final Provision provision;
+
+    public PlainAttrsPullCorrelationRule(final String[] plainSchemaNames, final Provision provision) {
+        this.plainSchemaNames = Arrays.asList(plainSchemaNames);
+        this.provision = provision;
+    }
+
+    @Override
+    public SearchCond getSearchCond(final ConnectorObject connObj) {
+        Map<String, MappingItem> mappingItems = new HashMap<>();
+        for (MappingItem item : MappingManagerImpl.getPullMappingItems(provision)) {
+            mappingItems.put(item.getIntAttrName(), item);
+        }
+
+        // search for anys by attribute(s) specified in the policy
+        SearchCond searchCond = null;
+
+        for (String schema : plainSchemaNames) {
+            Attribute attr = mappingItems.get(schema) == null
+                    ? null
+                    : connObj.getAttributeByName(mappingItems.get(schema).getExtAttrName());
+            if (attr == null) {
+                throw new IllegalArgumentException(
+                        "Connector object does not contains the attributes to perform the search: " + schema);
+            }
+
+            List<Object> values = attr.getValue();
+            for (MappingItemTransformer transformer
+                    : MappingManagerImpl.getMappingItemTransformers(mappingItems.get(schema))) {
+
+                values = transformer.beforePull(values);
+            }
+
+            AttributeCond.Type type;
+            String expression = null;
+
+            if (values == null || values.isEmpty() || (values.size() == 1 && values.get(0) == null)) {
+                type = AttributeCond.Type.ISNULL;
+            } else {
+                type = AttributeCond.Type.EQ;
+                expression = values.size() > 1
+                        ? values.toString()
+                        : values.get(0).toString();
+            }
+
+            SearchCond nodeCond;
+            // users: just key or username can be selected
+            // groups: just key or name can be selected
+            // any objects: just key can be selected
+            if ("key".equalsIgnoreCase(schema)
+                    || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
+
+                AnyCond cond = new AnyCond();
+                cond.setSchema(schema);
+                cond.setType(type);
+                cond.setExpression(expression);
+
+                nodeCond = SearchCond.getLeafCond(cond);
+            } else {
+                AttributeCond cond = new AttributeCond();
+                cond.setSchema(schema);
+                cond.setType(type);
+                cond.setExpression(expression);
+
+                nodeCond = SearchCond.getLeafCond(cond);
+            }
+
+            searchCond = searchCond == null
+                    ? nodeCond
+                    : SearchCond.getAndCond(searchCond, nodeCond);
+        }
+
+        return searchCond;
+    }
+
+}