syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [2/2] syncope git commit: [SYNCOPE-732] Implementation completed
Date Mon, 16 Nov 2015 14:22:03 GMT
[SYNCOPE-732] Implementation completed


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

Branch: refs/heads/master
Commit: b4a51a8a86905ee9e3e7395df442ab2aea2bae34
Parents: 4eaee19
Author: Francesco Chicchiriccò <ilgrosso@apache.org>
Authored: Mon Nov 16 15:21:52 2015 +0100
Committer: Francesco Chicchiriccò <ilgrosso@apache.org>
Committed: Mon Nov 16 15:21:52 2015 +0100

----------------------------------------------------------------------
 .../EntitlementSyncopeOperations.java           |   3 +-
 .../syncope/client/cli/commands/info/Info.java  |  11 +-
 .../client/cli/commands/info/InfoCommand.java   |   6 +-
 .../cli/commands/info/InfoResultManager.java    |  38 +++---
 .../client/cli/commands/task/TaskDetails.java   |   7 +-
 .../cli/commands/task/TaskResultManager.java    |   3 +-
 .../console/rest/ConfigurationRestClient.java   |   3 +-
 .../client/console/rest/PolicyRestClient.java   |   5 +-
 .../client/console/rest/ResourceRestClient.java |   3 +-
 .../client/console/rest/SchemaRestClient.java   |   8 +-
 .../client/console/rest/TaskRestClient.java     |   7 +-
 .../syncope/common/lib/to/SyncTaskTO.java       |  29 +++--
 .../apache/syncope/common/lib/to/SyncopeTO.java |  73 ++++++-----
 .../syncope/common/lib/types/SyncMode.java      |  29 +++++
 .../apache/syncope/core/logic/SyncopeLogic.java |   2 +
 .../init/ClassPathScanImplementationLookup.java |   6 +
 .../persistence/api/ImplementationLookup.java   |   1 +
 .../persistence/api/entity/task/SyncTask.java   |  13 +-
 .../jpa/entity/task/JPASyncTask.java            |  48 +++++---
 .../entity/ProvisioningTaskValidator.java       |  27 ++++
 .../core/persistence/jpa/outer/TaskTest.java    |   3 +
 .../test/resources/domains/MasterContent.xml    |  22 ++--
 .../core/provisioning/api/Connector.java        |  17 ++-
 .../api/sync/ReconciliationFilterBuilder.java   |  30 +++++
 .../provisioning/java/ConnectorFacadeProxy.java |  19 ++-
 .../java/data/TaskDataBinderImpl.java           |   9 +-
 .../DefaultReconciliationFilterBuilder.java     |  38 ++++++
 .../java/sync/DefaultSyncActions.java           |   2 +-
 .../provisioning/java/sync/SyncJobDelegate.java |  61 +++++----
 .../TestReconciliationFilterBuilder.java        |  35 ++++++
 .../fit/core/reference/MultitenancyITCase.java  |   5 +-
 .../fit/core/reference/PushTaskITCase.java      |   3 +-
 .../fit/core/reference/ReportITCase.java        |   3 +-
 .../fit/core/reference/ResourceITCase.java      |   2 +-
 .../fit/core/reference/SchedTaskITCase.java     |   3 +-
 .../fit/core/reference/SyncTaskITCase.java      | 123 ++++++++++++++-----
 36 files changed, 512 insertions(+), 185 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
index ead55e7..797678f 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.client.cli.commands.entitlement;
 
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 import org.apache.syncope.client.cli.SyncopeServices;
@@ -38,7 +37,7 @@ public class EntitlementSyncopeOperations {
 
     private final RoleSyncopeOperations roleSyncopeOperations = new RoleSyncopeOperations();
 
-    public List<String> list() {
+    public Set<String> list() {
         return syncopeTO.getEntitlements();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 a1f6956..bdb430f 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
@@ -101,7 +101,7 @@ public class Info {
         }
     }
 
-    public void connidLocation() {
+    public void connidLocations() {
         try {
             infoResultManager.printConnidLocations(syncopeTO.getConnIdLocations());
         } catch (final Exception ex) {
@@ -110,6 +110,15 @@ public class Info {
         }
     }
 
+    public void reconciliationFilterBuilders() {
+        try {
+            infoResultManager.printReconciliationFilterBuilders(syncopeTO.getReconciliationFilterBuilders());
+        } catch (final Exception ex) {
+            LOG.error("Information error", ex);
+            infoResultManager.genericError(ex.getMessage());
+        }
+    }
+
     public void logicActions() {
         try {
             infoResultManager.printLogicActions(syncopeTO.getLogicActions());

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 b2882d3..db2c283 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
@@ -59,7 +59,10 @@ public class InfoCommand extends AbstractCommand {
                 info.accountRules();
                 break;
             case CONNID_LOCATION:
-                info.connidLocation();
+                info.connidLocations();
+                break;
+            case RECONCILIATION_FILTER_BUILDERS:
+                info.reconciliationFilterBuilders();
                 break;
             case LOGIC_ACTIONS:
                 info.logicActions();
@@ -128,6 +131,7 @@ public class InfoCommand extends AbstractCommand {
         WORKFLOW_ADAPTER("--workflow-adapter-classes"),
         ACCOUNT_RULES("--account-rules-classes"),
         CONNID_LOCATION("--connid-locations"),
+        RECONCILIATION_FILTER_BUILDERS("--reconciliation-filter-builders"),
         LOGIC_ACTIONS("--logic-actions"),
         MAIL_TEMPLATES("--mail-templates"),
         MAPPING_ITEM_TRANSFORMERS("--mapping-item-transformers"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 c4eb206..f5f816f 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
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.client.cli.commands.info;
 
-import java.util.List;
+import java.util.Collection;
 import org.apache.syncope.client.cli.commands.CommonsResultManager;
 
 public class InfoResultManager extends CommonsResultManager {
@@ -57,85 +57,91 @@ public class InfoResultManager extends CommonsResultManager {
                 "Group      workflow adapter class: " + groupWorkflowAdapter);
     }
 
-    public void printAccountRules(final List<String> rules) {
+    public void printAccountRules(final Collection<String> rules) {
         for (final String accountRule : rules) {
             genericMessage("Account rule: " + accountRule);
         }
     }
 
-    public void printConnidLocations(final List<String> locations) {
+    public void printConnidLocations(final Collection<String> locations) {
         for (final String location : locations) {
             genericMessage("ConnId location: " + location);
         }
     }
 
-    public void printLogicActions(final List<String> actions) {
+    public void printReconciliationFilterBuilders(final Collection<String> reconciliationFilterBuilders) {
+        for (final String reconciliationFilterBuilder : reconciliationFilterBuilders) {
+            genericMessage("Reconciliation filter builder: " + reconciliationFilterBuilder);
+        }
+    }
+
+    public void printLogicActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Logic action: " + action);
         }
     }
 
-    public void printMailTemplates(final List<String> mailTemplates) {
+    public void printMailTemplates(final Collection<String> mailTemplates) {
         for (final String template : mailTemplates) {
             genericMessage("Mail template: " + template);
         }
     }
 
-    public void printMappingItemTransformers(final List<String> transformers) {
+    public void printMappingItemTransformers(final Collection<String> transformers) {
         for (final String tranformer : transformers) {
             genericMessage("Mapping item tranformer: " + tranformer);
         }
     }
 
-    public void printPasswordRules(final List<String> rules) {
+    public void printPasswordRules(final Collection<String> rules) {
         for (final String rule : rules) {
             genericMessage("Password rule: " + rule);
         }
     }
 
-    public void printCorrelationRules(final List<String> rules) {
+    public void printCorrelationRules(final Collection<String> rules) {
         for (final String rule : rules) {
             genericMessage("Correlation rule: " + rule);
         }
     }
 
-    public void printPropagationActions(final List<String> actions) {
+    public void printPropagationActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Propagation action: " + action);
         }
     }
 
-    public void printPushActions(final List<String> actions) {
+    public void printPushActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Push action: " + action);
         }
     }
 
-    public void printSyncActions(final List<String> actions) {
+    public void printSyncActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Sync action: " + action);
         }
     }
 
-    public void printCorrelationActions(final List<String> actions) {
+    public void printCorrelationActions(final Collection<String> actions) {
         for (final String action : actions) {
             genericMessage("Push correlation rule: " + action);
         }
     }
 
-    public void printReportlets(final List<String> reportlets) {
+    public void printReportlets(final Collection<String> reportlets) {
         for (final String reportlet : reportlets) {
             genericMessage("Reportlet: " + reportlet);
         }
     }
 
-    public void printJobs(final List<String> jobs) {
+    public void printJobs(final Collection<String> jobs) {
         for (final String job : jobs) {
             genericMessage("Task job: " + job);
         }
     }
 
-    public void printValidators(final List<String> validators) {
+    public void printValidators(final Collection<String> validators) {
         for (final String validator : validators) {
             genericMessage("Validator: " + validator);
         }
@@ -144,7 +150,7 @@ public class InfoResultManager extends CommonsResultManager {
     public void printPasswordGenerator(final String passwordGenerator) {
         genericMessage("Password generator class: " + passwordGenerator);
     }
-    
+
     public void printVirtualAttributeCacheClass(final String virAttrCache) {
         genericMessage("Virtual attribute cache class: " + virAttrCache);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 0e12590..4409c35 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
@@ -31,6 +31,7 @@ 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.TaskExecTO;
+import org.apache.syncope.common.lib.types.SyncMode;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,8 +52,8 @@ public class TaskDetails extends AbstractTaskCommand {
         if (input.parameterNumber() == 0) {
             try {
                 final Map<String, String> details = new LinkedMap<>();
-                final List<AbstractTaskTO> notificationTaskTOs
-                        = taskSyncopeOperations.list(TaskType.NOTIFICATION.name());
+                final List<AbstractTaskTO> notificationTaskTOs =
+                        taskSyncopeOperations.list(TaskType.NOTIFICATION.name());
                 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());
@@ -105,7 +106,7 @@ public class TaskDetails extends AbstractTaskCommand {
                             || ((SyncTaskTO) syncTaskTO).getExecutions().isEmpty()) {
                         syncNotExecuted++;
                     }
-                    if (((SyncTaskTO) syncTaskTO).isFullReconciliation()) {
+                    if (((SyncTaskTO) syncTaskTO).getSyncMode() == SyncMode.FULL_RECONCILIATION) {
                         syncFull++;
                     }
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 2441864..a1fdb0b 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
@@ -170,8 +170,7 @@ public class TaskResultManager extends CommonsResultManager {
         System.out.println("     realm destination: " + syncTaskTO.getDestinationRealm());
         System.out.println("     cron expression: " + syncTaskTO.getCronExpression());
         System.out.println("     description: " + syncTaskTO.getDescription());
-        System.out.println("     is full reconciliation: "
-                + syncTaskTO.isFullReconciliation());
+        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());

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
index d1ec74d..622a4ca 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.List;
+import java.util.Set;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.AttrLayoutType;
@@ -82,7 +83,7 @@ public class ConfigurationRestClient extends BaseRestClient {
         getService(ConfigurationService.class).delete(key);
     }
 
-    public List<String> getMailTemplates() {
+    public Set<String> getMailTemplates() {
         return SyncopeConsoleSession.get().getSyncopeTO().getMailTemplates();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 7f5964b..a3f44a1 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
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.rest;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.types.PolicyType;
@@ -69,8 +70,8 @@ public class PolicyRestClient extends BaseRestClient {
         getService(PolicyService.class).delete(id);
     }
 
-    public List<String> getCorrelationRuleClasses() {
-        List<String> rules = null;
+    public Set<String> getCorrelationRuleClasses() {
+        Set<String> rules = null;
 
         try {
             rules = SyncopeConsoleSession.get().getSyncopeTO().getSyncCorrelationRules();

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 3f7672d..e3bc2be 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.rest;
 
+import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
@@ -39,7 +40,7 @@ public class ResourceRestClient extends BaseRestClient {
     private static final long serialVersionUID = -6898907679835668987L;
 
     public List<String> getPropagationActionsClasses() {
-        return SyncopeConsoleSession.get().getSyncopeTO().getPropagationActions();
+        return new ArrayList<>(SyncopeConsoleSession.get().getSyncopeTO().getPropagationActions());
     }
 
     public List<ResourceTO> getAll() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
index ee95e5c..4d5f9fb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
@@ -51,10 +51,8 @@ public class SchemaRestClient extends BaseRestClient {
                 if (!allowed.contains(schema.getKey())) {
                     itor.remove();
                 }
-            } else {
-                if (allowed.contains(schema.getKey())) {
-                    itor.remove();
-                }
+            } else if (allowed.contains(schema.getKey())) {
+                itor.remove();
             }
         }
     }
@@ -197,7 +195,7 @@ public class SchemaRestClient extends BaseRestClient {
         List<String> response = null;
 
         try {
-            response = SyncopeConsoleSession.get().getSyncopeTO().getValidators();
+            response = new ArrayList<>(SyncopeConsoleSession.get().getSyncopeTO().getValidators());
         } catch (SyncopeClientException e) {
             LOG.error("While getting all validators", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 974b78c..30087ce 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
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.rest;
 
 import java.util.List;
+import java.util.Set;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
@@ -42,15 +43,15 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
 
     private static final long serialVersionUID = 6284485820911028843L;
 
-    public List<String> getJobClasses() {
+    public Set<String> getJobClasses() {
         return SyncopeConsoleSession.get().getSyncopeTO().getTaskJobs();
     }
 
-    public List<String> getSyncActionsClasses() {
+    public Set<String> getSyncActionsClasses() {
         return SyncopeConsoleSession.get().getSyncopeTO().getSyncActions();
     }
 
-    public List<String> getPushActionsClasses() {
+    public Set<String> getPushActionsClasses() {
         return SyncopeConsoleSession.get().getSyncopeTO().getPushActions();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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
index a6a7a8a..312f654 100644
--- 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
@@ -28,6 +28,7 @@ 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
@@ -36,13 +37,31 @@ 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<>();
 
-    private boolean fullReconciliation;
+    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;
@@ -56,12 +75,4 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO {
     public Map<String, AnyTO> getTemplates() {
         return templates;
     }
-
-    public boolean isFullReconciliation() {
-        return fullReconciliation;
-    }
-
-    public void setFullReconciliation(final boolean fullReconciliation) {
-        this.fullReconciliation = fullReconciliation;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
index c99532c..85b75cd 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -41,7 +41,7 @@ public class SyncopeTO extends AbstractBaseBean {
 
     private boolean pwdResetRequiringSecurityQuestions;
 
-    private final List<String> connIdLocations = new ArrayList<>();
+    private final Set<String> connIdLocations = new HashSet<>();
 
     private String anyObjectWorkflowAdapter;
 
@@ -59,33 +59,35 @@ public class SyncopeTO extends AbstractBaseBean {
 
     private String passwordGenerator;
 
-    private final List<String> entitlements = new ArrayList<>();
+    private final Set<String> entitlements = new HashSet<>();
 
-    private final List<String> reportlets = new ArrayList<>();
+    private final Set<String> reportlets = new HashSet<>();
 
-    private final List<String> accountRules = new ArrayList<>();
+    private final Set<String> accountRules = new HashSet<>();
 
-    private final List<String> passwordRules = new ArrayList<>();
+    private final Set<String> passwordRules = new HashSet<>();
 
-    private final List<String> mappingItemTransformers = new ArrayList<>();
+    private final Set<String> mappingItemTransformers = new HashSet<>();
 
-    private final List<String> taskJobs = new ArrayList<>();
+    private final Set<String> taskJobs = new HashSet<>();
 
-    private final List<String> logicActions = new ArrayList<>();
+    private final Set<String> reconciliationFilterBuilders = new HashSet<>();
 
-    private final List<String> propagationActions = new ArrayList<>();
+    private final Set<String> logicActions = new HashSet<>();
 
-    private final List<String> syncActions = new ArrayList<>();
+    private final Set<String> propagationActions = new HashSet<>();
 
-    private final List<String> pushActions = new ArrayList<>();
+    private final Set<String> syncActions = new HashSet<>();
 
-    private final List<String> syncCorrelationRules = new ArrayList<>();
+    private final Set<String> pushActions = new HashSet<>();
 
-    private final List<String> pushCorrelationRules = new ArrayList<>();
+    private final Set<String> syncCorrelationRules = new HashSet<>();
 
-    private final List<String> validators = new ArrayList<>();
+    private final Set<String> pushCorrelationRules = new HashSet<>();
 
-    private final List<String> mailTemplates = new ArrayList<>();
+    private final Set<String> validators = new HashSet<>();
+
+    private final Set<String> mailTemplates = new HashSet<>();
 
     public String getVersion() {
         return version;
@@ -106,7 +108,7 @@ public class SyncopeTO extends AbstractBaseBean {
     @XmlElementWrapper(name = "connIdLocations")
     @XmlElement(name = "connIdLocation")
     @JsonProperty("connIdLocations")
-    public List<String> getConnIdLocations() {
+    public Set<String> getConnIdLocations() {
         return connIdLocations;
     }
 
@@ -149,98 +151,105 @@ public class SyncopeTO extends AbstractBaseBean {
     @XmlElementWrapper(name = "entitlements")
     @XmlElement(name = "entitlement")
     @JsonProperty("entitlements")
-    public List<String> getEntitlements() {
+    public Set<String> getEntitlements() {
         return entitlements;
     }
 
     @XmlElementWrapper(name = "reportlets")
     @XmlElement(name = "reportlet")
     @JsonProperty("reportlets")
-    public List<String> getReportlets() {
+    public Set<String> getReportlets() {
         return reportlets;
     }
 
     @XmlElementWrapper(name = "accountRules")
     @XmlElement(name = "accountRule")
     @JsonProperty("accountRules")
-    public List<String> getAccountRules() {
+    public Set<String> getAccountRules() {
         return accountRules;
     }
 
     @XmlElementWrapper(name = "passwordRules")
     @XmlElement(name = "passwordRule")
     @JsonProperty("passwordRules")
-    public List<String> getPasswordRules() {
+    public Set<String> getPasswordRules() {
         return passwordRules;
     }
 
     @XmlElementWrapper(name = "mappingItemTransformers")
     @XmlElement(name = "mappingItemTransformer")
     @JsonProperty("mappingItemTransformers")
-    public List<String> getMappingItemTransformers() {
+    public Set<String> getMappingItemTransformers() {
         return mappingItemTransformers;
     }
 
     @XmlElementWrapper(name = "taskJobs")
     @XmlElement(name = "taskJob")
     @JsonProperty("taskJobs")
-    public List<String> getTaskJobs() {
+    public Set<String> getTaskJobs() {
         return taskJobs;
     }
 
+    @XmlElementWrapper(name = "reconciliationFilterBuilders")
+    @XmlElement(name = "reconciliationFilterBuilder")
+    @JsonProperty("reconciliationFilterBuilders")
+    public Set<String> getReconciliationFilterBuilders() {
+        return reconciliationFilterBuilders;
+    }
+
     @XmlElementWrapper(name = "logicActions")
     @XmlElement(name = "logicAction")
     @JsonProperty("logicActions")
-    public List<String> getLogicActions() {
+    public Set<String> getLogicActions() {
         return logicActions;
     }
 
     @XmlElementWrapper(name = "propagationActions")
     @XmlElement(name = "propagationAction")
     @JsonProperty("propagationActions")
-    public List<String> getPropagationActions() {
+    public Set<String> getPropagationActions() {
         return propagationActions;
     }
 
     @XmlElementWrapper(name = "syncActions")
     @XmlElement(name = "syncAction")
     @JsonProperty("syncActions")
-    public List<String> getSyncActions() {
+    public Set<String> getSyncActions() {
         return syncActions;
     }
 
     @XmlElementWrapper(name = "pushActions")
     @XmlElement(name = "pushAction")
     @JsonProperty("pushActions")
-    public List<String> getPushActions() {
+    public Set<String> getPushActions() {
         return pushActions;
     }
 
     @XmlElementWrapper(name = "syncCorrelationRules")
     @XmlElement(name = "syncCorrelationRule")
     @JsonProperty("syncCorrelationRules")
-    public List<String> getSyncCorrelationRules() {
+    public Set<String> getSyncCorrelationRules() {
         return syncCorrelationRules;
     }
 
     @XmlElementWrapper(name = "pushCorrelationRules")
     @XmlElement(name = "pushCorrelationRule")
     @JsonProperty("pushCorrelationRules")
-    public List<String> getPushCorrelationRules() {
+    public Set<String> getPushCorrelationRules() {
         return pushCorrelationRules;
     }
 
     @XmlElementWrapper(name = "validators")
     @XmlElement(name = "validator")
     @JsonProperty("validators")
-    public List<String> getValidators() {
+    public Set<String> getValidators() {
         return validators;
     }
 
     @XmlElementWrapper(name = "mailTemplates")
     @XmlElement(name = "mailTemplate")
     @JsonProperty("mailTemplates")
-    public List<String> getMailTemplates() {
+    public Set<String> getMailTemplates() {
         return mailTemplates;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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
new file mode 100644
index 0000000..afa9f19
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncMode.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 SyncMode {
+    FULL_RECONCILIATION,
+    FILTERED_RECONCILIATION,
+    INCREMENTAL;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 dcd24ad..f2a9c3b 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
@@ -136,6 +136,8 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
         syncopeTO.getPasswordRules().addAll(implLookup.getClassNames(Type.PASSWORD_RULE));
         syncopeTO.getMappingItemTransformers().addAll(implLookup.getClassNames(Type.MAPPING_ITEM_TRANSFORMER));
         syncopeTO.getTaskJobs().addAll(implLookup.getClassNames(Type.TASKJOBDELEGATE));
+        syncopeTO.getReconciliationFilterBuilders().
+                addAll(implLookup.getClassNames(Type.RECONCILIATION_FILTER_BUILDER));
         syncopeTO.getLogicActions().addAll(implLookup.getClassNames(Type.LOGIC_ACTIONS));
         syncopeTO.getPropagationActions().addAll(implLookup.getClassNames(Type.PROPAGATION_ACTIONS));
         syncopeTO.getSyncActions().addAll(implLookup.getClassNames(Type.SYNC_ACTIONS));

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 5147a39..3fc4fc4 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
@@ -53,6 +53,7 @@ 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.sync.ReconciliationFilterBuilder;
 
 /**
  * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
@@ -93,6 +94,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
         scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRule.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(MappingItemTransformer.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(ReconciliationFilterBuilder.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PropagationActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
@@ -144,6 +146,10 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                     classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
                 }
 
+                if (ReconciliationFilterBuilder.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+                    classNames.get(Type.RECONCILIATION_FILTER_BUILDER).add(bd.getBeanClassName());
+                }
+
                 if (LogicActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
                     classNames.get(Type.LOGIC_ACTIONS).add(bd.getBeanClassName());
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 fa8847f..6b84c99 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
@@ -35,6 +35,7 @@ public interface ImplementationLookup extends SyncopeLoader {
         PASSWORD_RULE,
         MAPPING_ITEM_TRANSFORMER,
         TASKJOBDELEGATE,
+        RECONCILIATION_FILTER_BUILDER,
         LOGIC_ACTIONS,
         PROPAGATION_ACTIONS,
         SYNC_ACTIONS,

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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
index bc0c2b2..ca07988 100644
--- 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
@@ -19,18 +19,23 @@
 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 {
 
-    Realm getDestinatioRealm();
+    SyncMode getSyncMode();
 
-    void setDestinationRealm(Realm destinationRealm);
+    void setSyncMode(SyncMode syncMode);
+
+    String getReconciliationFilterBuilderClassName();
 
-    boolean isFullReconciliation();
+    void setReconciliationFilterBuilderClassName(String reconciliationFilterBuilderClassName);
 
-    void setFullReconciliation(boolean condition);
+    Realm getDestinatioRealm();
+
+    void setDestinationRealm(Realm destinationRealm);
 
     boolean add(AnyTemplateSyncTask template);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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
index 8cc8b05..935d76c 100644
--- 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
@@ -22,21 +22,22 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import javax.persistence.Basic;
 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.Max;
-import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.CollectionUtils;
 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;
@@ -51,6 +52,12 @@ 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;
 
@@ -64,11 +71,6 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
     private List<JPAAnyTemplateSyncTask> templates = new ArrayList<>();
 
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer fullReconciliation;
-
     /**
      * Default constructor.
      */
@@ -77,6 +79,26 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @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;
     }
@@ -93,16 +115,6 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public boolean isFullReconciliation() {
-        return isBooleanAsInteger(fullReconciliation);
-    }
-
-    @Override
-    public void setFullReconciliation(final boolean fullReconciliation) {
-        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
-    }
-
-    @Override
     public boolean add(final AnyTemplateSyncTask template) {
         checkType(template, JPAAnyTemplateSyncTask.class);
         return this.templates.add((JPAAnyTemplateSyncTask) template);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 e397bce..72b421e 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,11 +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.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.sync.PushActions;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
+import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
 
 public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
 
@@ -78,6 +81,30 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                     }
                 }
             }
+
+            if (isValid && task instanceof SyncTask
+                    && ((SyncTask) task).getSyncMode() == SyncMode.FILTERED_RECONCILIATION) {
+
+                Class<?> filterBuilderClass = null;
+                boolean isAssignable = false;
+                try {
+                    filterBuilderClass = Class.forName(((SyncTask) task).getReconciliationFilterBuilderClassName());
+                    isAssignable = ReconciliationFilterBuilder.class.isAssignableFrom(filterBuilderClass);
+                } catch (Exception e) {
+                    LOG.error("Invalid {} specified",
+                            ReconciliationFilterBuilder.class.getName(), SyncActions.class.getName(), e);
+                    isValid = false;
+                }
+
+                if (filterBuilderClass == null || !isAssignable) {
+                    isValid = false;
+
+                    context.disableDefaultConstraintViolation();
+                    context.buildConstraintViolationWithTemplate(
+                            getTemplate(EntityViolationType.InvalidProvisioningTask, "Invalid class name")).
+                            addPropertyNode("reconciliationFilterBuilderClassName").addConstraintViolation();
+                }
+            }
         }
 
         return isValid;

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 53f88d8..05a22ed 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,6 +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.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
@@ -217,6 +218,7 @@ public class TaskTest extends AbstractTest {
         SyncTask task = entityFactory.newEntity(SyncTask.class);
         task.setName("saveSyncTask");
         task.setDescription("SyncTask description");
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
         task.add(template);
         task.setCronExpression("BLA BLA");
         task.setMatchingRule(MatchingRule.UPDATE);
@@ -274,6 +276,7 @@ public class TaskTest extends AbstractTest {
         task.setResource(resource);
         task.setName("issueSYNCOPE144");
         task.setDescription("issueSYNCOPE144 Description");
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
         task.getActionsClassNames().add(SyncActions.class.getName());
         task.setMatchingRule(MatchingRule.UPDATE);
         task.setUnmatchingRule(UnmatchingRule.PROVISION);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 7e71cfd..73fee53 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -967,8 +967,8 @@ under the License.
         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" fullReconciliation="0"
-        unmatchingRule="ASSIGN" matchingRule="UPDATE"/>
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
+        syncMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE"/>
   <AnyTemplateSyncTask id="41" syncTask_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":"type","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"
@@ -980,7 +980,7 @@ under the License.
         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" 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" fullReconciliation="1"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <AnyTemplateSyncTask id="71" syncTask_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":"type","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;"]}]}'/>
@@ -989,13 +989,13 @@ under the License.
   <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-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" fullReconciliation="1"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" syncMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="10" name="TestDB Sync Task" resource_name="resource-db-sync"
-        destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
+        destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="11" name="LDAP Sync Task" resource_name="resource-ldap"
-        destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
+        destinationRealm_id="1" syncMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <AnyTemplateSyncTask id="1" syncTask_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":[]}'/>
@@ -1003,7 +1003,7 @@ under the License.
                        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,"adynMembershipCond":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.sync.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" fullReconciliation="1"
+        destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" syncMode="FULL_RECONCILIATION"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="PushTask" type="PUSH" id="13" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"         
@@ -1062,23 +1062,23 @@ under the License.
   <AnyFilter id="231" anyType_name="USER" pushTask_id="23" filter="username==_NO_ONE_"/>
   <AnyFilter id="232" anyType_name="GROUP" pushTask_id="23" filter="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" fullReconciliation="0"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <AnyTemplateSyncTask id="3" syncTask_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"
                        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,"adynMembershipCond":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" fullReconciliation="0"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
         unmatchingRule="IGNORE" matchingRule="UNLINK"/>
   <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" fullReconciliation="0"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" syncMode="INCREMENTAL"
         unmatchingRule="ASSIGN" matchingRule="IGNORE"/>
   <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" fullReconciliation="0"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" syncMode="INCREMENTAL"
         unmatchingRule="PROVISION" matchingRule="UPDATE"/>
 
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 c93c2c4..7aed2ca 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,6 +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.sync.ReconciliationFilterBuilder;
 
 /**
  * Entry point for making requests on underlying connector bundles.
@@ -103,7 +104,21 @@ public interface Connector {
      * @param handler to be used to handle deltas.
      * @param options ConnId's OperationOptions.
      */
-    void getAllObjects(ObjectClass objectClass, SyncResultsHandler handler, OperationOptions options);
+    void fullReconciliation(ObjectClass objectClass, SyncResultsHandler handler, OperationOptions options);
+
+    /**
+     * Fetches remote objects (for use during filtered reconciliation).
+     *
+     * @param objectClass ConnId's object class.
+     * @param filterBuilder reconciliation filter builder
+     * @param handler to be used to handle deltas.
+     * @param options ConnId's OperationOptions.
+     */
+    void filteredReconciliation(
+            ObjectClass objectClass,
+            ReconciliationFilterBuilder filterBuilder,
+            SyncResultsHandler handler,
+            OperationOptions options);
 
     /**
      * Sync remote objects from a connector instance.

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java
new file mode 100644
index 0000000..874215b
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
+
+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/b4a51a8a/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 86add58..3454985 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
@@ -66,6 +66,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.ClassUtils;
+import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
 
 public class ConnectorFacadeProxy implements Connector {
 
@@ -332,10 +333,22 @@ public class ConnectorFacadeProxy implements Connector {
     }
 
     @Override
-    public void getAllObjects(
-            final ObjectClass objectClass, final SyncResultsHandler handler, final OperationOptions options) {
+    public void fullReconciliation(
+            final ObjectClass objectClass,
+            final SyncResultsHandler handler,
+            final OperationOptions options) {
+
+        filteredReconciliation(objectClass, null, handler, options);
+    }
+
+    @Override
+    public void filteredReconciliation(
+            final ObjectClass objectClass,
+            final ReconciliationFilterBuilder filterBuilder,
+            final SyncResultsHandler handler,
+            final OperationOptions options) {
 
-        search(objectClass, null, new ResultsHandler() {
+        search(objectClass, filterBuilder == null ? null : filterBuilder.build(), new ResultsHandler() {
 
             @Override
             public boolean handle(final ConnectorObject obj) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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 3207bd2..5e69ad6 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
@@ -140,6 +140,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             final SyncTask syncTask = (SyncTask) task;
             final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO;
 
+            syncTask.setSyncMode(syncTaskTO.getSyncMode());
+            syncTask.setReconciliationFilterBuilderClassName(syncTaskTO.getReconciliationFilterBuilderClassName());
+
             syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
 
             syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName());
@@ -175,8 +178,6 @@ public class TaskDataBinderImpl implements TaskDataBinder {
                     return syncTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey());
                 }
             });
-
-            syncTask.setFullReconciliation(syncTaskTO.isFullReconciliation());
         }
 
         // 3. fill the remaining fields
@@ -289,7 +290,9 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         taskTO.setEndDate(latestExec == null ? null : latestExec.getEndDate());
 
         for (TaskExec execution : task.getExecs()) {
-            taskTO.getExecutions().add(getTaskExecTO(execution));
+            if (execution != null) {
+                taskTO.getExecutions().add(getTaskExecTO(execution));
+            }
         }
 
         switch (taskUtils.getType()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java
new file mode 100644
index 0000000..2c75928
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
+
+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.sync.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/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
index 1612b6d..9045e2a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
@@ -27,7 +27,7 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
 
 /**
- * Default (empty) implementation of SyncActions.
+ * Default (empty) implementation of {@link SyncActions}.
  */
 public abstract class DefaultSyncActions implements SyncActions {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
index c5fad73..cf0f020 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
@@ -50,6 +50,7 @@ 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.sync.ReconciliationFilterBuilder;
 
 public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
 
@@ -166,11 +167,6 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
                 }
 
                 try {
-                    SyncToken latestSyncToken = null;
-                    if (!syncTask.isFullReconciliation()) {
-                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
-                    }
-
                     Set<MappingItem> linkinMappingItems = new HashSet<>();
                     for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
                         linkinMappingItems.add(virSchema.asLinkingMappingItem());
@@ -179,29 +175,42 @@ public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
                             provision.getMapping().getItems().iterator(),
                             linkinMappingItems.iterator());
 
-                    if (syncTask.isFullReconciliation()) {
-                        connector.getAllObjects(
-                                provision.getObjectClass(),
-                                handler,
-                                MappingUtils.buildOperationOptions(mapItems));
-                    } else {
-                        connector.sync(
-                                provision.getObjectClass(),
-                                provision.getSyncToken(),
-                                handler,
-                                MappingUtils.buildOperationOptions(mapItems));
-                    }
-
-                    if (!dryRun && !syncTask.isFullReconciliation()) {
-                        try {
-                            provision.setSyncToken(latestSyncToken);
-                            resourceDAO.save(provision.getResource());
-                        } catch (Exception e) {
-                            throw new JobExecutionException("While updating SyncToken", e);
-                        }
+                    switch (syncTask.getSyncMode()) {
+                        case INCREMENTAL:
+                            SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                            connector.sync(
+                                    provision.getObjectClass(),
+                                    provision.getSyncToken(),
+                                    handler,
+                                    MappingUtils.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,
+                                    MappingUtils.buildOperationOptions(mapItems));
+                            break;
+
+                        case FULL_RECONCILIATION:
+                        default:
+                            connector.fullReconciliation(
+                                    provision.getObjectClass(),
+                                    handler,
+                                    MappingUtils.buildOperationOptions(mapItems));
+                            break;
                     }
                 } catch (Throwable t) {
-                    throw new JobExecutionException("While syncing on connector", t);
+                    throw new JobExecutionException("While syncing from connector", t);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/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
new file mode 100644
index 0000000..f6b5c2d
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * 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.provisioning.java.sync.DefaultReconciliationFilterBuilder;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.filter.Filter;
+import org.identityconnectors.framework.common.objects.filter.FilterBuilder;
+
+public class TestReconciliationFilterBuilder extends DefaultReconciliationFilterBuilder {
+
+    private static final Filter EQUALS = FilterBuilder.equalTo(AttributeBuilder.build("SURNAME", "Rossi"));
+
+    @Override
+    public Filter build() {
+        return EQUALS;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
index 2a9dffe..5aac6c0 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/MultitenancyITCase.java
@@ -49,6 +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.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.DomainService;
 import org.apache.syncope.common.rest.api.service.LoggerService;
@@ -186,9 +187,9 @@ public class MultitenancyITCase extends AbstractITCase {
         // create sync task
         SyncTaskTO task = new SyncTaskTO();
         task.setName("LDAP Sync Task");
-        task.setDestinationRealm("/");
+        task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
         task.setResource(resource.getKey());
-        task.setFullReconciliation(true);
+        task.setSyncMode(SyncMode.FULL_RECONCILIATION);
         task.setPerformCreate(true);
 
         response = adminClient.getService(TaskService.class).create(task);

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index 91b7840..bf294f6 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.lib.SyncopeClient;
@@ -67,7 +66,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void getPushActionsClasses() {
-        List<String> actions = syncopeService.info().getPushActions();
+        Set<String> actions = syncopeService.info().getPushActions();
         assertNotNull(actions);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
index 86f3b1d..bed0aa4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.fail;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Set;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
@@ -53,7 +54,7 @@ public class ReportITCase extends AbstractITCase {
 
     @Test
     public void getReportletClasses() {
-        List<String> reportlets = syncopeService.info().getReportlets();
+        Set<String> reportlets = syncopeService.info().getReportlets();
         assertNotNull(reportlets);
         assertFalse(reportlets.isEmpty());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
index 90f5796..99be00a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
@@ -103,7 +103,7 @@ public class ResourceITCase extends AbstractITCase {
 
     @Test
     public void getPropagationActionsClasses() {
-        List<String> actions = syncopeService.info().getPropagationActions();
+        Set<String> actions = syncopeService.info().getPropagationActions();
         assertNotNull(actions);
         assertFalse(actions.isEmpty());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b4a51a8a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index 42493af..614f5d3 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.List;
+import java.util.Set;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
@@ -47,7 +48,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void getJobClasses() {
-        List<String> jobClasses = syncopeService.info().getTaskJobs();
+        Set<String> jobClasses = syncopeService.info().getTaskJobs();
         assertNotNull(jobClasses);
         assertFalse(jobClasses.isEmpty());
     }


Mime
View raw message