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/09 12:52:37 UTC

[01/17] syncope git commit: [SYNCOPE-701] Removing unwanted core/misc dependency

Repository: syncope
Updated Branches:
  refs/heads/master 8557d2acf -> 28569df55


[SYNCOPE-701] Removing unwanted core/misc dependency


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

Branch: refs/heads/master
Commit: 0d09829ed34b62b942ed68216e8b08ffd8861335
Parents: 8557d2a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Mar 8 16:27:57 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Mar 9 12:41:03 2016 +0100

----------------------------------------------------------------------
 client/enduser/pom.xml                          |  9 +-------
 .../enduser/SyncopeEnduserApplication.java      | 24 ++++++++++----------
 .../enduser/resources/AbstractBaseResource.java |  3 +++
 .../client/enduser/resources/InfoResource.java  |  5 ++--
 .../client/enduser/resources/LoginResource.java |  9 ++------
 .../enduser/resources/SchemaResource.java       |  3 +--
 .../resources/SecurityQuestionResource.java     |  5 ++--
 .../resources/SyncopeAnyClassTypeResource.java  |  5 ++--
 .../resources/SyncopeAnyTypeResource.java       |  3 +--
 .../enduser/resources/SyncopeGroupResource.java |  3 +--
 .../resources/SyncopeResourceResource.java      |  3 +--
 .../resources/UserSelfCreateResource.java       |  9 ++++----
 .../enduser/resources/UserSelfReadResource.java |  3 +--
 .../resources/UserSelfUpdateResource.java       |  9 +++-----
 14 files changed, 36 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml
index f6132cb..eca2124 100644
--- a/client/enduser/pom.xml
+++ b/client/enduser/pom.xml
@@ -38,13 +38,6 @@ under the License.
   </properties>
   
   <dependencies>
-    
-    <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-misc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
     <dependency> 
       <groupId>javax.servlet</groupId> 
       <artifactId>javax.servlet-api</artifactId>
@@ -175,7 +168,7 @@ under the License.
       <groupId>org.webjars</groupId>
       <artifactId>jquery-ui</artifactId>
     </dependency>
-    
+
     <!--Logging-->
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
index 2c6f348..9a3e32e 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -52,7 +52,7 @@ import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
-import org.springframework.util.Assert;
+import org.apache.wicket.util.lang.Args;
 
 public class SyncopeEnduserApplication extends WebApplication implements Serializable {
 
@@ -105,30 +105,30 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
             throw new WicketRuntimeException("Could not read " + ENDUSER_PROPERTIES, e);
         }
         version = props.getProperty("version");
-        Assert.notNull(version, "<version> not set");
+        Args.notNull(version, "<version> not set");
         site = props.getProperty("site");
-        Assert.notNull(site, "<site> not set");
+        Args.notNull(site, "<site> not set");
         license = props.getProperty("license");
-        Assert.notNull(license, "<license> not set");
+        Args.notNull(license, "<license> not set");
         anonymousUser = props.getProperty("anonymousUser");
-        Assert.notNull(anonymousUser, "<anonymousUser> not set");
+        Args.notNull(anonymousUser, "<anonymousUser> not set");
         anonymousKey = props.getProperty("anonymousKey");
-        Assert.notNull(anonymousKey, "<anonymousKey> not set");
+        Args.notNull(anonymousKey, "<anonymousKey> not set");
 
         captchaEnabled = Boolean.parseBoolean(props.getProperty("captcha"));
-        Assert.notNull(captchaEnabled, "<captcha> not set");
+        Args.notNull(captchaEnabled, "<captcha> not set");
 
         xsrfEnabled = Boolean.parseBoolean(props.getProperty("xsrf"));
-        Assert.notNull(xsrfEnabled, "<xsrf> not set");
+        Args.notNull(xsrfEnabled, "<xsrf> not set");
 
         String scheme = props.getProperty("scheme");
-        Assert.notNull(scheme, "<scheme> not set");
+        Args.notNull(scheme, "<scheme> not set");
         String host = props.getProperty("host");
-        Assert.notNull(host, "<host> not set");
+        Args.notNull(host, "<host> not set");
         String port = props.getProperty("port");
-        Assert.notNull(port, "<port> not set");
+        Args.notNull(port, "<port> not set");
         String rootPath = props.getProperty("rootPath");
-        Assert.notNull(rootPath, "<rootPath> not set");
+        Args.notNull(rootPath, "<rootPath> not set");
 
         clientFactory = new SyncopeClientFactoryBean().setAddress(scheme + "://" + host + ":" + port + "/" + rootPath);
         clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.JSON);

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
index 6c402db..a5ebe63 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.enduser.resources;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserApplication;
@@ -34,6 +35,8 @@ public abstract class AbstractBaseResource extends AbstractResource {
 
     private static final Logger LOG = LoggerFactory.getLogger(AbstractBaseResource.class);
 
+    protected static final ObjectMapper MAPPER = new ObjectMapper();
+
     protected final boolean isSelfRegistrationAllowed() {
         Boolean result = null;
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
index acfbac9..8b36907 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.adapters.PlatformInfoAdapter;
 import org.apache.syncope.client.enduser.util.SaltGenerator;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.util.cookies.CookieUtils;
 import org.slf4j.Logger;
@@ -57,9 +56,9 @@ public class InfoResource extends AbstractBaseResource {
                 @Override
                 public void writeData(final IResource.Attributes attributes) throws IOException {
                     attributes.getResponse().write(
-                            POJOHelper.serialize(
+                            MAPPER.writeValueAsString(
                                     PlatformInfoAdapter.toPlatformInfoRequest(
-                                    SyncopeEnduserSession.get().getPlatformInfo())));
+                                            SyncopeEnduserSession.get().getPlatformInfo())));
                 }
             });
             response.setStatusCode(Response.Status.OK.getStatusCode());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
index 28d19a3..db99669 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
@@ -24,7 +24,6 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.model.Credentials;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.util.io.IOUtils;
@@ -37,12 +36,8 @@ public class LoginResource extends AbstractBaseResource {
 
     private static final Logger LOG = LoggerFactory.getLogger(LoginResource.class);
 
-    public LoginResource() {
-    }
-
     @Override
     protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-
         AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
 
         try {
@@ -54,8 +49,8 @@ public class LoginResource extends AbstractBaseResource {
                 return response;
             }
 
-            Credentials credentials = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()),
-                    Credentials.class);
+            Credentials credentials = MAPPER.readValue(
+                    IOUtils.toString(request.getInputStream()), Credentials.class);
             final String username = credentials.getUsername();
             final String password = credentials.getPassword().isEmpty() ? null : credentials.getPassword();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index 4783b79..3b32d05 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -34,7 +34,6 @@ import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
 import org.slf4j.Logger;
@@ -94,7 +93,7 @@ public class SchemaResource extends AbstractBaseResource {
 
                 @Override
                 public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(POJOHelper.serialize(new SchemaResponse().
+                    attributes.getResponse().write(MAPPER.writeValueAsString(new SchemaResponse().
                             plainSchemas(plainSchemas).
                             derSchemas(derSchemas).
                             virSchemas(virSchemas)));

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
index 7e79b1b..0893c22 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
@@ -72,7 +71,7 @@ public class SecurityQuestionResource extends AbstractBaseResource {
 
                     @Override
                     public void writeData(final IResource.Attributes attributes) throws IOException {
-                        attributes.getResponse().write(POJOHelper.serialize(securityQuestionTO));
+                        attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTO));
                     }
                 });
             } else {
@@ -82,7 +81,7 @@ public class SecurityQuestionResource extends AbstractBaseResource {
 
                     @Override
                     public void writeData(final IResource.Attributes attributes) throws IOException {
-                        attributes.getResponse().write(POJOHelper.serialize(securityQuestionTOs));
+                        attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTOs));
                     }
                 });
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
index 2528150..bdb6f98 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +37,7 @@ public class SyncopeAnyClassTypeResource extends AbstractBaseResource {
 
     private final AnyTypeClassService anyTypeClassService;
 
-    public SyncopeAnyClassTypeResource() {        
+    public SyncopeAnyClassTypeResource() {
         anyTypeClassService = SyncopeEnduserSession.get().getService(AnyTypeClassService.class);
     }
 
@@ -64,7 +63,7 @@ public class SyncopeAnyClassTypeResource extends AbstractBaseResource {
 
                 @Override
                 public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(POJOHelper.serialize(anyTypeClassTOs));
+                    attributes.getResponse().write(MAPPER.writeValueAsString(anyTypeClassTOs));
                 }
             });
             response.setStatusCode(Response.Status.OK.getStatusCode());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
index 7d2bcde..9c9b1ad 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
@@ -24,7 +24,6 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,7 +63,7 @@ public class SyncopeAnyTypeResource extends AbstractBaseResource {
 
                 @Override
                 public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(POJOHelper.serialize(anyTypeTO));
+                    attributes.getResponse().write(MAPPER.writeValueAsString(anyTypeTO));
                 }
             });
             response.setStatusCode(Response.Status.OK.getStatusCode());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
index 8ae82ce..09e3b85 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
@@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
 import org.apache.syncope.common.rest.api.service.GroupService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,7 +68,7 @@ public class SyncopeGroupResource extends AbstractBaseResource {
 
                 @Override
                 public void writeData(final Attributes attributes) throws IOException {
-                    attributes.getResponse().write(POJOHelper.serialize(groupTOs));
+                    attributes.getResponse().write(MAPPER.writeValueAsString(groupTOs));
                 }
             });
             response.setStatusCode(Response.Status.OK.getStatusCode());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
index 8d08ac2..8a6d0a9 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
 import org.slf4j.Logger;
@@ -65,7 +64,7 @@ public class SyncopeResourceResource extends AbstractBaseResource {
 
                 @Override
                 public void writeData(final IResource.Attributes attributes) throws IOException {
-                    attributes.getResponse().write(POJOHelper.serialize(resourceTOs));
+                    attributes.getResponse().write(MAPPER.writeValueAsString(resourceTOs));
                 }
             });
             response.setStatusCode(Response.Status.OK.getStatusCode());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
index 88059d6..4ab2ca5 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -58,7 +57,7 @@ public class UserSelfCreateResource extends AbstractBaseResource {
 
             String jsonString = request.getReader().readLine();
 
-            final UserTO userTO = POJOHelper.deserialize(jsonString, UserTO.class);
+            final UserTO userTO = MAPPER.readValue(jsonString, UserTO.class);
 
             if (!captchaCheck(request.getHeader("captcha"), request.getSession().getAttribute(
                     SyncopeEnduserConstants.CAPTCHA_SESSION_KEY).toString())) {
@@ -79,7 +78,7 @@ public class UserSelfCreateResource extends AbstractBaseResource {
                         attributes.getResponse().write(res.getStatusInfo().getFamily().equals(
                                 Response.Status.Family.SUCCESSFUL)
                                         ? responseMessage.append("User: ").append(userTO.getUsername()).append(
-                                                " successfully created")
+                                        " successfully created")
                                         : new StringBuilder().append("ErrorMessage{{ ").
                                         append(res.getStatusInfo().getReasonPhrase()).append(" }}"));
                     }
@@ -88,8 +87,8 @@ public class UserSelfCreateResource extends AbstractBaseResource {
             } else {
                 response.setError(Response.Status.FORBIDDEN.getStatusCode(), new StringBuilder().
                         append("ErrorMessage{{").append(userTO == null
-                                        ? "Request received is not valid }}"
-                                        : "Self registration not allowed }}").toString());
+                        ? "Request received is not valid }}"
+                        : "Self registration not allowed }}").toString());
             }
 
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
index 2cca020..2411adf 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
@@ -22,7 +22,6 @@ import java.io.IOException;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
 import org.slf4j.Logger;
@@ -56,7 +55,7 @@ public class UserSelfReadResource extends AbstractBaseResource {
                 return response;
             }
 
-            final String selfTOJson = POJOHelper.serialize(SyncopeEnduserSession.get().getSelfTO());
+            final String selfTOJson = MAPPER.writeValueAsString(SyncopeEnduserSession.get().getSelfTO());
 
             response.setWriteCallback(new WriteCallback() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
index d913e6e..8e2c148 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.wicket.request.resource.AbstractResource;
 import org.apache.wicket.request.resource.IResource;
 import org.slf4j.Logger;
@@ -39,14 +38,12 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
 
     private final UserSelfService userSelfService;
 
-
     public UserSelfUpdateResource() {
         userSelfService = SyncopeEnduserSession.get().getService(UserSelfService.class);
     }
 
     @Override
     protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-
         AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
 
         try {
@@ -59,14 +56,14 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
 
             String jsonString = request.getReader().readLine();
 
-            final UserTO userTO = POJOHelper.deserialize(jsonString, UserTO.class);
+            final UserTO userTO = MAPPER.readValue(jsonString, UserTO.class);
 
             if (!captchaCheck(request.getHeader("captcha"), request.getSession().getAttribute(
                     SyncopeEnduserConstants.CAPTCHA_SESSION_KEY).toString())) {
                 LOG.error("Entered captcha is not matching");
                 throw new Exception("Entered captcha is not matching");
             }
-            
+
             LOG.debug("User {} id updating himself", userTO.getUsername());
 
             // update user
@@ -74,7 +71,7 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
 
             final String responseMessage = res.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)
                     ? new StringBuilder().append("User").append(userTO.getUsername()).append(
-                            " successfully updated").toString()
+                    " successfully updated").toString()
                     : new StringBuilder().append("ErrorMessage{{ ").
                     append(res.getStatusInfo().getReasonPhrase()).append(" }}").toString();
 


[16/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
deleted file mode 100644
index 9c64734..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
+++ /dev/null
@@ -1,241 +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.misc.jexl;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.jexl3.JexlBuilder;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.JexlEngine;
-import org.apache.commons.jexl3.JexlException;
-import org.apache.commons.jexl3.JexlExpression;
-import org.apache.commons.jexl3.JxltEngine;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.provisioning.api.DerAttrHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
- */
-public final class JexlUtils {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
-
-    private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
-
-    private static JexlEngine JEXL_ENGINE;
-
-    private static JexlEngine getEngine() {
-        synchronized (LOG) {
-            if (JEXL_ENGINE == null) {
-                JEXL_ENGINE = new JexlBuilder().
-                        uberspect(new ClassFreeUberspect()).
-                        loader(new EmptyClassLoader()).
-                        cache(512).
-                        silent(false).
-                        strict(false).
-                        create();
-            }
-        }
-
-        return JEXL_ENGINE;
-    }
-
-    public static JxltEngine newJxltEngine() {
-        return getEngine().createJxltEngine(false);
-    }
-
-    public static boolean isExpressionValid(final String expression) {
-        boolean result;
-        try {
-            getEngine().createExpression(expression);
-            result = true;
-        } catch (JexlException e) {
-            LOG.error("Invalid jexl expression: " + expression, e);
-            result = false;
-        }
-
-        return result;
-    }
-
-    public static String evaluate(final String expression, final JexlContext jexlContext) {
-        String result = StringUtils.EMPTY;
-
-        if (StringUtils.isNotBlank(expression) && jexlContext != null) {
-            try {
-                JexlExpression jexlExpression = getEngine().createExpression(expression);
-                Object evaluated = jexlExpression.evaluate(jexlContext);
-                if (evaluated != null) {
-                    result = evaluated.toString();
-                }
-            } catch (Exception e) {
-                LOG.error("Error while evaluating JEXL expression: " + expression, e);
-            }
-        } else {
-            LOG.debug("Expression not provided or invalid context");
-        }
-
-        return result;
-    }
-
-    public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
-        JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
-
-        try {
-            for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
-                Class<?> type = desc.getPropertyType();
-                String fieldName = desc.getName();
-
-                if ((!fieldName.startsWith("pc"))
-                        && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
-                        && (!Iterable.class.isAssignableFrom(type))
-                        && (!type.isArray())) {
-
-                    try {
-                        Object fieldValue;
-                        if (desc.getReadMethod() == null) {
-                            final Field field = object.getClass().getDeclaredField(fieldName);
-                            field.setAccessible(true);
-                            fieldValue = field.get(object);
-                        } else {
-                            fieldValue = desc.getReadMethod().invoke(object);
-                        }
-
-                        context.set(fieldName, fieldValue == null
-                                ? StringUtils.EMPTY
-                                : (type.equals(Date.class)
-                                ? FormatUtils.format((Date) fieldValue, false)
-                                : fieldValue));
-
-                        LOG.debug("Add field {} with value {}", fieldName, fieldValue);
-                    } catch (Exception iae) {
-                        LOG.error("Reading '{}' value error", fieldName, iae);
-                    }
-                }
-            }
-        } catch (IntrospectionException ie) {
-            LOG.error("Reading class attributes error", ie);
-        }
-
-        if (object instanceof Any) {
-            Any<?> any = (Any<?>) object;
-            if (any.getRealm() != null) {
-                context.set("realm", any.getRealm().getName());
-            }
-        }
-
-        return context;
-    }
-
-    public static void addPlainAttrsToContext(
-            final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
-
-        for (PlainAttr<?> attr : attrs) {
-            if (attr.getSchema() != null) {
-                List<String> attrValues = attr.getValuesAsStrings();
-                String expressionValue = attrValues.isEmpty()
-                        ? StringUtils.EMPTY
-                        : attrValues.get(0);
-
-                LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
-
-                jexlContext.set(attr.getSchema().getKey(), expressionValue);
-            }
-        }
-    }
-
-    public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
-        Map<DerSchema, String> derAttrs =
-                ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
-
-        for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
-            jexlContext.set(entry.getKey().getKey(), entry.getValue());
-        }
-    }
-
-    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
-        JexlContext jexlContext = new MapContext();
-        addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
-        addDerAttrsToContext(any, jexlContext);
-
-        return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
-    }
-
-    public static String evaluate(final String expression, final AnyTO anyTO) {
-        final JexlContext context = new MapContext();
-
-        addFieldsToContext(anyTO, context);
-
-        for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
-            List<String> values = plainAttr.getValues();
-            String expressionValue = values.isEmpty()
-                    ? StringUtils.EMPTY
-                    : values.get(0);
-
-            LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
-
-            context.set(plainAttr.getSchema(), expressionValue);
-        }
-        for (AttrTO derAttr : anyTO.getDerAttrs()) {
-            List<String> values = derAttr.getValues();
-            String expressionValue = values.isEmpty()
-                    ? StringUtils.EMPTY
-                    : values.get(0);
-
-            LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
-
-            context.set(derAttr.getSchema(), expressionValue);
-        }
-        for (AttrTO virAttr : anyTO.getVirAttrs()) {
-            List<String> values = virAttr.getValues();
-            String expressionValue = values.isEmpty()
-                    ? StringUtils.EMPTY
-                    : values.get(0);
-
-            LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
-
-            context.set(virAttr.getSchema(), expressionValue);
-        }
-
-        // Evaluate expression using the context prepared before
-        return evaluate(expression, context);
-    }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private JexlUtils() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
deleted file mode 100644
index 0d3eff7..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
+++ /dev/null
@@ -1,32 +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.misc.policy;
-
-public class AccountPolicyException extends PolicyException {
-
-    private static final long serialVersionUID = 2779416455067691813L;
-
-    public AccountPolicyException() {
-        super();
-    }
-
-    public AccountPolicyException(final String message) {
-        super(message);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
deleted file mode 100644
index 4b13807..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
+++ /dev/null
@@ -1,37 +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.misc.policy;
-
-/**
- * Raise when the merge of two or more PasswordRuleconf instances led to an inconsistent condition.
- *
- * @see org.apache.syncope.common.lib.policy.PasswordRuleConf
- */
-public class InvalidPasswordRuleConf extends Exception {
-
-    private static final long serialVersionUID = 4810651743226663580L;
-
-    public InvalidPasswordRuleConf(final String msg) {
-        super(msg);
-    }
-
-    public InvalidPasswordRuleConf(final String msg, final Exception e) {
-        super(msg, e);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
deleted file mode 100644
index 7bf530b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
+++ /dev/null
@@ -1,32 +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.misc.policy;
-
-public class PasswordPolicyException extends PolicyException {
-
-    private static final long serialVersionUID = 8072104484395278469L;
-
-    public PasswordPolicyException() {
-        super();
-    }
-
-    public PasswordPolicyException(final String message) {
-        super(message);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
deleted file mode 100644
index 5a2ef36..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
+++ /dev/null
@@ -1,32 +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.misc.policy;
-
-public class PolicyException extends RuntimeException {
-
-    private static final long serialVersionUID = -6082115004491662910L;
-
-    public PolicyException() {
-        super();
-    }
-
-    public PolicyException(final String message) {
-        super(message);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
deleted file mode 100644
index ecb4e6c..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
+++ /dev/null
@@ -1,50 +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.misc.policy;
-
-import java.util.regex.Pattern;
-
-public final class PolicyPattern {
-
-    public static final Pattern DIGIT = Pattern.compile(".*\\d+.*");
-
-    public static final Pattern ALPHA_LOWERCASE = Pattern.compile(".*[a-z]+.*");
-
-    public static final Pattern ALPHA_UPPERCASE = Pattern.compile(".*[A-Z]+.*");
-
-    public static final Pattern FIRST_DIGIT = Pattern.compile("\\d.*");
-
-    public static final Pattern LAST_DIGIT = Pattern.compile(".*\\d");
-
-    public static final Pattern ALPHANUMERIC = Pattern.compile(".*\\w.*");
-
-    public static final Pattern FIRST_ALPHANUMERIC = Pattern.compile("\\w.*");
-
-    public static final Pattern LAST_ALPHANUMERIC = Pattern.compile(".*\\w");
-
-    public static final Pattern NON_ALPHANUMERIC = Pattern.compile(".*\\W.*");
-
-    public static final Pattern FIRST_NON_ALPHANUMERIC = Pattern.compile("\\W.*");
-
-    public static final Pattern LAST_NON_ALPHANUMERIC = Pattern.compile(".*\\W");
-
-    private PolicyPattern() {
-        // private constructor for static utility class
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java
deleted file mode 100644
index 77b959b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.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.core.misc.search;
-
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-
-/**
- * Converts FIQL expressions to Syncope's {@link SearchCond}.
- */
-public final class SearchCondConverter {
-
-    /**
-     * Parses a FIQL expression into Syncope's <tt>SearchCond</tt>, using CXF's <tt>FiqlParser</tt>.
-     *
-     * @param fiqlExpression FIQL string
-     * @param realms optional realm to provide to {@link SearchCondVisitor}
-     * @return {@link SearchCond} instance for given FIQL expression
-     * @see FiqlParser
-     */
-    public static SearchCond convert(final String fiqlExpression, final String... realms) {
-        FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
-                SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
-
-        try {
-            SearchCondVisitor searchCondVisitor = new SearchCondVisitor();
-            if (realms != null && realms.length > 0) {
-                searchCondVisitor.setRealm(realms[0]);
-            }
-            searchCondVisitor.visit(fiqlParser.parse(fiqlExpression));
-            return searchCondVisitor.getQuery();
-        } catch (Exception e) {
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
-            sce.getElements().add(fiqlExpression);
-            sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
-            throw sce;
-        }
-    }
-
-    private SearchCondConverter() {
-        // empty constructor for static utility class        
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
deleted file mode 100644
index 2e281cf..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
+++ /dev/null
@@ -1,222 +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.misc.search;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.cxf.jaxrs.ext.search.ConditionType;
-import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.SearchCondition;
-import org.apache.cxf.jaxrs.ext.search.SearchUtils;
-import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
-import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.search.SpecialAttr;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
-import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
-
-/**
- * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
- */
-public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean, SearchCond> {
-
-    private String realm;
-
-    private SearchCond searchCond;
-
-    public SearchCondVisitor() {
-        super(null);
-    }
-
-    public void setRealm(final String realm) {
-        this.realm = realm;
-    }
-
-    private AttributeCond createAttributeCond(final String schema) {
-        AttributeCond attributeCond = EntityTOUtils.ANY_FIELDS.contains(schema)
-                ? new AnyCond()
-                : new AttributeCond();
-        attributeCond.setSchema(schema);
-        return attributeCond;
-    }
-
-    private SearchCond visitPrimitive(final SearchCondition<SearchBean> sc) {
-        String name = getRealPropertyName(sc.getStatement().getProperty());
-        SpecialAttr specialAttrName = SpecialAttr.fromString(name);
-
-        String value = SearchUtils.toSqlWildcardString(sc.getStatement().getValue().toString(), false).
-                replaceAll("\\\\_", "_");
-        SpecialAttr specialAttrValue = SpecialAttr.fromString(value);
-
-        AttributeCond attributeCond = createAttributeCond(name);
-        attributeCond.setExpression(value);
-
-        SearchCond leaf;
-        switch (sc.getConditionType()) {
-            case EQUALS:
-            case NOT_EQUALS:
-                if (specialAttrName == null) {
-                    if (specialAttrValue != null && specialAttrValue == SpecialAttr.NULL) {
-                        attributeCond.setType(AttributeCond.Type.ISNULL);
-                        attributeCond.setExpression(null);
-                    } else if (value.indexOf('%') == -1) {
-                        attributeCond.setType(AttributeCond.Type.EQ);
-                    } else {
-                        attributeCond.setType(AttributeCond.Type.LIKE);
-                    }
-
-                    leaf = SearchCond.getLeafCond(attributeCond);
-                } else {
-                    switch (specialAttrName) {
-                        case TYPE:
-                            AnyTypeCond typeCond = new AnyTypeCond();
-                            typeCond.setAnyTypeName(value);
-                            leaf = SearchCond.getLeafCond(typeCond);
-                            break;
-
-                        case RESOURCES:
-                            ResourceCond resourceCond = new ResourceCond();
-                            resourceCond.setResourceName(value);
-                            leaf = SearchCond.getLeafCond(resourceCond);
-                            break;
-
-                        case GROUPS:
-                            MembershipCond groupCond = new MembershipCond();
-                            groupCond.setGroupKey(Long.valueOf(value));
-                            leaf = SearchCond.getLeafCond(groupCond);
-                            break;
-
-                        case RELATIONSHIPS:
-                            RelationshipCond relationshipCond = new RelationshipCond();
-                            relationshipCond.setAnyObjectKey(Long.valueOf(value));
-                            leaf = SearchCond.getLeafCond(relationshipCond);
-                            break;
-
-                        case RELATIONSHIP_TYPES:
-                            RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
-                            relationshipTypeCond.setRelationshipTypeKey(value);
-                            leaf = SearchCond.getLeafCond(relationshipTypeCond);
-                            break;
-
-                        case ROLES:
-                            RoleCond roleCond = new RoleCond();
-                            roleCond.setRoleKey(value);
-                            leaf = SearchCond.getLeafCond(roleCond);
-                            break;
-
-                        case ASSIGNABLE:
-                            AssignableCond assignableCond = new AssignableCond();
-                            assignableCond.setRealmFullPath(realm);
-                            leaf = SearchCond.getLeafCond(assignableCond);
-                            break;
-
-                        default:
-                            throw new IllegalArgumentException(
-                                    String.format("Special attr name %s is not supported", specialAttrName));
-                    }
-                }
-                if (sc.getConditionType() == ConditionType.NOT_EQUALS) {
-                    if (leaf.getAttributeCond() != null
-                            && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
-
-                        leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
-                    } else if (leaf.getAnyCond() != null
-                            && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
-
-                        leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
-                    } else {
-                        leaf = SearchCond.getNotLeafCond(leaf);
-                    }
-                }
-                break;
-
-            case GREATER_OR_EQUALS:
-                attributeCond.setType(AttributeCond.Type.GE);
-                leaf = SearchCond.getLeafCond(attributeCond);
-                break;
-
-            case GREATER_THAN:
-                attributeCond.setType(AttributeCond.Type.GT);
-                leaf = SearchCond.getLeafCond(attributeCond);
-                break;
-
-            case LESS_OR_EQUALS:
-                attributeCond.setType(AttributeCond.Type.LE);
-                leaf = SearchCond.getLeafCond(attributeCond);
-                break;
-
-            case LESS_THAN:
-                attributeCond.setType(AttributeCond.Type.LT);
-                leaf = SearchCond.getLeafCond(attributeCond);
-                break;
-
-            default:
-                throw new IllegalArgumentException(
-                        String.format("Condition type %s is not supported", sc.getConditionType().name()));
-        }
-
-        return leaf;
-    }
-
-    private SearchCond visitCompount(final SearchCondition<SearchBean> sc) {
-        List<SearchCond> searchConds = new ArrayList<>();
-        for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
-            searchConds.add(searchCondition.getStatement() == null
-                    ? visitCompount(searchCondition)
-                    : visitPrimitive(searchCondition));
-        }
-
-        SearchCond compound;
-        switch (sc.getConditionType()) {
-            case AND:
-                compound = SearchCond.getAndCond(searchConds);
-                break;
-
-            case OR:
-                compound = SearchCond.getOrCond(searchConds);
-                break;
-
-            default:
-                throw new IllegalArgumentException(
-                        String.format("Condition type %s is not supported", sc.getConditionType().name()));
-        }
-
-        return compound;
-    }
-
-    @Override
-    public void visit(final SearchCondition<SearchBean> sc) {
-        searchCond = sc.getStatement() == null
-                ? visitCompount(sc)
-                : visitPrimitive(sc);
-    }
-
-    @Override
-    public SearchCond getQuery() {
-        return searchCond;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
deleted file mode 100644
index e7b9fc0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ /dev/null
@@ -1,126 +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.misc.security;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-
-public final class AuthContextUtils {
-
-    public interface Executable<T> {
-
-        T exec();
-    }
-
-    public static String getUsername() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
-    }
-
-    public static void updateUsername(final String newUsername) {
-        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
-        UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
-                new User(newUsername, "FAKE_PASSWORD", auth.getAuthorities()),
-                auth.getCredentials(), auth.getAuthorities());
-        newAuth.setDetails(auth.getDetails());
-        SecurityContextHolder.getContext().setAuthentication(newAuth);
-    }
-
-    public static Map<String, Set<String>> getAuthorizations() {
-        Map<String, Set<String>> result = null;
-
-        SecurityContext ctx = SecurityContextHolder.getContext();
-        if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
-            result = new HashMap<>();
-            for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
-                if (authority instanceof SyncopeGrantedAuthority) {
-                    result.put(
-                            SyncopeGrantedAuthority.class.cast(authority).getAuthority(),
-                            SyncopeGrantedAuthority.class.cast(authority).getRealms());
-                }
-            }
-        }
-
-        return MapUtils.emptyIfNull(result);
-    }
-
-    public static String getDomain() {
-        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
-        String domainKey = auth != null && auth.getDetails() instanceof SyncopeAuthenticationDetails
-                ? SyncopeAuthenticationDetails.class.cast(auth.getDetails()).getDomain()
-                : null;
-        if (StringUtils.isBlank(domainKey)) {
-            domainKey = SyncopeConstants.MASTER_DOMAIN;
-        }
-
-        return domainKey;
-    }
-
-    private static void setFakeAuth(final String domain) {
-        List<GrantedAuthority> authorities = CollectionUtils.collect(EntitlementsHolder.getInstance().getValues(),
-                new Transformer<String, GrantedAuthority>() {
-
-            @Override
-            public GrantedAuthority transform(final String entitlement) {
-                return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
-            }
-        }, new ArrayList<GrantedAuthority>());
-
-        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
-                new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
-                        "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
-        auth.setDetails(new SyncopeAuthenticationDetails(domain));
-        SecurityContextHolder.getContext().setAuthentication(auth);
-    }
-
-    public static <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
-        SecurityContext ctx = SecurityContextHolder.getContext();
-        setFakeAuth(domainKey);
-        try {
-            return executable.exec();
-        } finally {
-            SecurityContextHolder.clearContext();
-            SecurityContextHolder.setContext(ctx);
-        }
-    }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private AuthContextUtils() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
deleted file mode 100644
index 7e880b4..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
+++ /dev/null
@@ -1,318 +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.misc.security;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Resource;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.SetUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.DomainDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Domain;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-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.user.User;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationServiceException;
-import org.springframework.security.authentication.DisabledException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Domain-sensible (via {@code @Transactional} access to authentication / authorization data.
- *
- * @see SyncopeAuthenticationProvider
- * @see SyncopeAuthenticationDetails
- */
-public class AuthDataAccessor {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
-
-    protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    @Resource(name = "anonymousUser")
-    protected String anonymousUser;
-
-    @Autowired
-    protected DomainDAO domainDAO;
-
-    @Autowired
-    protected ConfDAO confDAO;
-
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    protected ConnectorFactory connFactory;
-
-    @Autowired
-    protected AuditManager auditManager;
-
-    @Autowired
-    protected MappingUtils mappingUtils;
-
-    @Transactional(readOnly = true)
-    public Domain findDomain(final String key) {
-        Domain domain = domainDAO.find(key);
-        if (domain == null) {
-            throw new AuthenticationServiceException("Could not find domain " + key);
-        }
-        return domain;
-    }
-
-    /**
-     * Attempts to authenticate the given credentials against internal storage and pass-through resources (if
-     * configured): the first succeeding causes global success.
-     *
-     * @param authentication given credentials
-     * @return {@code null} if no matching user was found, authentication result otherwise
-     */
-    @Transactional(noRollbackFor = DisabledException.class)
-    public Pair<Long, Boolean> authenticate(final Authentication authentication) {
-        Long key = null;
-        Boolean authenticated = null;
-
-        User user = userDAO.find(authentication.getName());
-        if (user != null) {
-            key = user.getKey();
-            authenticated = false;
-
-            if (user.isSuspended() != null && user.isSuspended()) {
-                throw new DisabledException("User " + user.getUsername() + " is suspended");
-            }
-
-            CPlainAttr authStatuses = confDAO.find("authentication.statuses");
-            if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
-                throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
-            }
-
-            boolean userModified = false;
-            authenticated = authenticate(user, authentication.getCredentials().toString());
-            if (authenticated) {
-                if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
-                    user.setLastLoginDate(new Date());
-                    userModified = true;
-                }
-
-                if (user.getFailedLogins() != 0) {
-                    user.setFailedLogins(0);
-                    userModified = true;
-                }
-
-            } else {
-                user.setFailedLogins(user.getFailedLogins() + 1);
-                userModified = true;
-            }
-
-            if (userModified) {
-                userDAO.save(user);
-            }
-        }
-
-        return ImmutablePair.of(key, authenticated);
-    }
-
-    protected boolean authenticate(final User user, final String password) {
-        boolean authenticated = ENCRYPTOR.verify(password, user.getCipherAlgorithm(), user.getPassword());
-        LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
-
-        for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
-                itor.hasNext() && !authenticated;) {
-
-            ExternalResource resource = itor.next();
-            String connObjectKey = null;
-            try {
-                connObjectKey = mappingUtils.getConnObjectKeyValue(user, resource.getProvision(anyTypeDAO.findUser()));
-                Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
-                if (uid != null) {
-                    authenticated = true;
-                }
-            } catch (Exception e) {
-                LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
-            }
-            LOG.debug("{} authenticated on {} as {}: {}",
-                    user.getUsername(), resource.getKey(), connObjectKey, authenticated);
-        }
-
-        return authenticated;
-    }
-
-    protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
-        Set<? extends ExternalResource> result = null;
-
-        // 1. look for assigned resources, pick the ones whose account policy has authentication resources
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
-                if (result == null) {
-                    result = resource.getAccountPolicy().getResources();
-                } else {
-                    result.retainAll(resource.getAccountPolicy().getResources());
-                }
-            }
-        }
-
-        // 2. look for realms, pick the ones whose account policy has authentication resources
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
-                if (result == null) {
-                    result = realm.getAccountPolicy().getResources();
-                } else {
-                    result.retainAll(realm.getAccountPolicy().getResources());
-                }
-            }
-        }
-
-        return SetUtils.emptyIfNull(result);
-    }
-
-    @Transactional(readOnly = true)
-    public void audit(
-            final AuditElements.EventCategoryType type,
-            final String category,
-            final String subcategory,
-            final String event,
-            final AuditElements.Result result,
-            final Object before,
-            final Object output,
-            final Object... input) {
-
-        auditManager.audit(type, category, subcategory, event, result, before, output, input);
-    }
-
-    @Transactional
-    public Set<SyncopeGrantedAuthority> load(final String username) {
-        final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
-        if (anonymousUser.equals(username)) {
-            authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.ANONYMOUS));
-        } else if (adminUser.equals(username)) {
-            CollectionUtils.collect(
-                    EntitlementsHolder.getInstance().getValues(),
-                    new Transformer<String, SyncopeGrantedAuthority>() {
-
-                @Override
-                public SyncopeGrantedAuthority transform(final String entitlement) {
-                    return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
-                }
-            }, authorities);
-        } else {
-            User user = userDAO.find(username);
-            if (user == null) {
-                throw new UsernameNotFoundException("Could not find any user with id " + username);
-            }
-
-            if (user.isMustChangePassword()) {
-                authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.MUST_CHANGE_PASSWORD));
-            } else {
-                final Map<String, Set<String>> entForRealms = new HashMap<>();
-
-                // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
-                // statically and dynamically
-                for (final Role role : userDAO.findAllRoles(user)) {
-                    IterableUtils.forEach(role.getEntitlements(), new Closure<String>() {
-
-                        @Override
-                        public void execute(final String entitlement) {
-                            Set<String> realms = entForRealms.get(entitlement);
-                            if (realms == null) {
-                                realms = new HashSet<>();
-                                entForRealms.put(entitlement, realms);
-                            }
-
-                            CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
-
-                                @Override
-                                public String transform(final Realm realm) {
-                                    return realm.getFullPath();
-                                }
-                            }, realms);
-                        }
-                    });
-                }
-
-                // Give group entitlements for owned groups
-                for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
-                    for (String entitlement : Arrays.asList(
-                            StandardEntitlement.GROUP_READ,
-                            StandardEntitlement.GROUP_UPDATE,
-                            StandardEntitlement.GROUP_DELETE)) {
-
-                        Set<String> realms = entForRealms.get(entitlement);
-                        if (realms == null) {
-                            realms = new HashSet<>();
-                            entForRealms.put(entitlement, realms);
-                        }
-
-                        realms.add(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
-                    }
-                }
-
-                // Finally normalize realms for each given entitlement and generate authorities
-                for (Map.Entry<String, Set<String>> entry : entForRealms.entrySet()) {
-                    SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entry.getKey());
-                    authority.addRealms(RealmUtils.normalize(entry.getValue()));
-                    authorities.add(authority);
-                }
-            }
-        }
-
-        return authorities;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
deleted file mode 100644
index 9652f73..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
+++ /dev/null
@@ -1,334 +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.misc.security;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Generate random passwords according to given policies.
- * When no minimum and / or maximum length are specified, default values are set.
- *
- * <strong>WARNING</strong>: This class only takes {@link DefaultPasswordRuleConf} into account.
- */
-public class DefaultPasswordGenerator implements PasswordGenerator {
-
-    private static final char[] SPECIAL_CHARS = { '!', 'ÂŁ', '%', '&', '(', ')', '?', '#', '$' };
-
-    private static final int VERY_MIN_LENGTH = 0;
-
-    private static final int VERY_MAX_LENGTH = 64;
-
-    private static final int MIN_LENGTH_IF_ZERO = 6;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Override
-    public String generate(final User user) throws InvalidPasswordRuleConf {
-        List<PasswordRuleConf> ruleConfs = new ArrayList<>();
-
-        for (Realm ancestor : realmDAO.findAncestors(user.getRealm())) {
-            if (ancestor.getPasswordPolicy() != null) {
-                ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
-            }
-        }
-
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            if (resource.getPasswordPolicy() != null) {
-                ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
-            }
-        }
-
-        return generate(ruleConfs);
-    }
-
-    @Override
-    public String generate(final List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf {
-        List<DefaultPasswordRuleConf> defaultRuleConfs = new ArrayList<>();
-        for (PasswordRuleConf ruleConf : ruleConfs) {
-            if (ruleConf instanceof DefaultPasswordRuleConf) {
-                defaultRuleConfs.add((DefaultPasswordRuleConf) ruleConf);
-            }
-        }
-
-        DefaultPasswordRuleConf ruleConf = merge(defaultRuleConfs);
-        check(ruleConf);
-        return generate(ruleConf);
-    }
-
-    private DefaultPasswordRuleConf merge(final List<DefaultPasswordRuleConf> defaultRuleConfs) {
-        DefaultPasswordRuleConf result = new DefaultPasswordRuleConf();
-        result.setMinLength(VERY_MIN_LENGTH);
-        result.setMaxLength(VERY_MAX_LENGTH);
-
-        for (DefaultPasswordRuleConf ruleConf : defaultRuleConfs) {
-            if (ruleConf.getMinLength() > result.getMinLength()) {
-                result.setMinLength(ruleConf.getMinLength());
-            }
-
-            if ((ruleConf.getMaxLength() != 0) && ((ruleConf.getMaxLength() < result.getMaxLength()))) {
-                result.setMaxLength(ruleConf.getMaxLength());
-            }
-            result.getPrefixesNotPermitted().addAll(ruleConf.getPrefixesNotPermitted());
-            result.getSuffixesNotPermitted().addAll(ruleConf.getSuffixesNotPermitted());
-
-            if (!result.isNonAlphanumericRequired()) {
-                result.setNonAlphanumericRequired(ruleConf.isNonAlphanumericRequired());
-            }
-
-            if (!result.isAlphanumericRequired()) {
-                result.setAlphanumericRequired(ruleConf.isAlphanumericRequired());
-            }
-            if (!result.isDigitRequired()) {
-                result.setDigitRequired(ruleConf.isDigitRequired());
-            }
-
-            if (!result.isLowercaseRequired()) {
-                result.setLowercaseRequired(ruleConf.isLowercaseRequired());
-            }
-            if (!result.isUppercaseRequired()) {
-                result.setUppercaseRequired(ruleConf.isUppercaseRequired());
-            }
-            if (!result.isMustStartWithDigit()) {
-                result.setMustStartWithDigit(ruleConf.isMustStartWithDigit());
-            }
-            if (!result.isMustntStartWithDigit()) {
-                result.setMustntStartWithDigit(ruleConf.isMustntStartWithDigit());
-            }
-            if (!result.isMustEndWithDigit()) {
-                result.setMustEndWithDigit(ruleConf.isMustEndWithDigit());
-            }
-            if (result.isMustntEndWithDigit()) {
-                result.setMustntEndWithDigit(ruleConf.isMustntEndWithDigit());
-            }
-            if (!result.isMustStartWithAlpha()) {
-                result.setMustStartWithAlpha(ruleConf.isMustStartWithAlpha());
-            }
-            if (!result.isMustntStartWithAlpha()) {
-                result.setMustntStartWithAlpha(ruleConf.isMustntStartWithAlpha());
-            }
-            if (!result.isMustStartWithNonAlpha()) {
-                result.setMustStartWithNonAlpha(ruleConf.isMustStartWithNonAlpha());
-            }
-            if (!result.isMustntStartWithNonAlpha()) {
-                result.setMustntStartWithNonAlpha(ruleConf.isMustntStartWithNonAlpha());
-            }
-            if (!result.isMustEndWithNonAlpha()) {
-                result.setMustEndWithNonAlpha(ruleConf.isMustEndWithNonAlpha());
-            }
-            if (!result.isMustntEndWithNonAlpha()) {
-                result.setMustntEndWithNonAlpha(ruleConf.isMustntEndWithNonAlpha());
-            }
-            if (!result.isMustEndWithAlpha()) {
-                result.setMustEndWithAlpha(ruleConf.isMustEndWithAlpha());
-            }
-            if (!result.isMustntEndWithAlpha()) {
-                result.setMustntEndWithAlpha(ruleConf.isMustntEndWithAlpha());
-            }
-            if (!result.isUsernameAllowed()) {
-                result.setUsernameAllowed(ruleConf.isUsernameAllowed());
-            }
-        }
-
-        if (result.getMinLength() == 0) {
-            result.setMinLength(
-                    result.getMaxLength() < MIN_LENGTH_IF_ZERO ? result.getMaxLength() : MIN_LENGTH_IF_ZERO);
-        }
-
-        return result;
-    }
-
-    private void check(final DefaultPasswordRuleConf defaultPasswordRuleConf)
-            throws InvalidPasswordRuleConf {
-
-        if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustntEndWithAlpha()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustEndWithAlpha and mustntEndWithAlpha are both true");
-        }
-        if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustEndWithDigit()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustEndWithAlpha and mustEndWithDigit are both true");
-        }
-        if (defaultPasswordRuleConf.isMustEndWithDigit() && defaultPasswordRuleConf.isMustntEndWithDigit()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustEndWithDigit and mustntEndWithDigit are both true");
-        }
-        if (defaultPasswordRuleConf.isMustEndWithNonAlpha() && defaultPasswordRuleConf.isMustntEndWithNonAlpha()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustEndWithNonAlpha and mustntEndWithNonAlpha are both true");
-        }
-        if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustntStartWithAlpha()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustStartWithAlpha and mustntStartWithAlpha are both true");
-        }
-        if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustStartWithDigit()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustStartWithAlpha and mustStartWithDigit are both true");
-        }
-        if (defaultPasswordRuleConf.isMustStartWithDigit() && defaultPasswordRuleConf.isMustntStartWithDigit()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustStartWithDigit and mustntStartWithDigit are both true");
-        }
-        if (defaultPasswordRuleConf.isMustStartWithNonAlpha() && defaultPasswordRuleConf.isMustntStartWithNonAlpha()) {
-            throw new InvalidPasswordRuleConf(
-                    "mustStartWithNonAlpha and mustntStartWithNonAlpha are both true");
-        }
-        if (defaultPasswordRuleConf.getMinLength() > defaultPasswordRuleConf.getMaxLength()) {
-            throw new InvalidPasswordRuleConf(
-                    "Minimun length (" + defaultPasswordRuleConf.getMinLength() + ")"
-                    + "is greater than maximum length (" + defaultPasswordRuleConf.getMaxLength() + ")");
-        }
-    }
-
-    private String generate(final DefaultPasswordRuleConf ruleConf) {
-        String[] generatedPassword = new String[ruleConf.getMinLength()];
-
-        for (int i = 0; i < generatedPassword.length; i++) {
-            generatedPassword[i] = StringUtils.EMPTY;
-        }
-
-        checkStartChar(generatedPassword, ruleConf);
-
-        checkEndChar(generatedPassword, ruleConf);
-
-        checkRequired(generatedPassword, ruleConf);
-
-        for (int firstEmptyChar = firstEmptyChar(generatedPassword);
-                firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
-
-            generatedPassword[firstEmptyChar] = SecureRandomUtils.generateRandomLetter();
-        }
-
-        checkPrefixAndSuffix(generatedPassword, ruleConf);
-
-        return StringUtils.join(generatedPassword);
-    }
-
-    private void checkStartChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
-        if (ruleConf.isMustStartWithAlpha()) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
-        }
-        if (ruleConf.isMustStartWithNonAlpha() || ruleConf.isMustStartWithDigit()) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
-        }
-        if (ruleConf.isMustntStartWithAlpha()) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
-        }
-        if (ruleConf.isMustntStartWithDigit()) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
-        }
-        if (ruleConf.isMustntStartWithNonAlpha()) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
-        }
-
-        if (StringUtils.EMPTY.equals(generatedPassword[0])) {
-            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
-        }
-    }
-
-    private void checkEndChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
-        if (ruleConf.isMustEndWithAlpha()) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
-        }
-        if (ruleConf.isMustEndWithNonAlpha() || ruleConf.isMustEndWithDigit()) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
-        }
-
-        if (ruleConf.isMustntEndWithAlpha()) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
-        }
-        if (ruleConf.isMustntEndWithDigit()) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
-        }
-        if (ruleConf.isMustntEndWithNonAlpha()) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
-        }
-
-        if (StringUtils.EMPTY.equals(generatedPassword[ruleConf.getMinLength() - 1])) {
-            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
-        }
-    }
-
-    private int firstEmptyChar(final String[] generatedPStrings) {
-        int index = 0;
-        while (!generatedPStrings[index].isEmpty()) {
-            index++;
-        }
-        return index;
-    }
-
-    private void checkRequired(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
-        if (ruleConf.isDigitRequired()
-                && !PolicyPattern.DIGIT.matcher(StringUtils.join(generatedPassword)).matches()) {
-
-            generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtils.generateRandomNumber();
-        }
-
-        if (ruleConf.isUppercaseRequired()
-                && !PolicyPattern.ALPHA_UPPERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
-
-            generatedPassword[firstEmptyChar(generatedPassword)] =
-                    SecureRandomUtils.generateRandomLetter().toUpperCase();
-        }
-
-        if (ruleConf.isLowercaseRequired()
-                && !PolicyPattern.ALPHA_LOWERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
-
-            generatedPassword[firstEmptyChar(generatedPassword)] =
-                    SecureRandomUtils.generateRandomLetter().toLowerCase();
-        }
-
-        if (ruleConf.isNonAlphanumericRequired()
-                && !PolicyPattern.NON_ALPHANUMERIC.matcher(StringUtils.join(generatedPassword)).matches()) {
-
-            generatedPassword[firstEmptyChar(generatedPassword)] =
-                    SecureRandomUtils.generateRandomSpecialCharacter(SPECIAL_CHARS);
-        }
-    }
-
-    private void checkPrefixAndSuffix(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
-        for (String prefix : ruleConf.getPrefixesNotPermitted()) {
-            if (StringUtils.join(generatedPassword).startsWith(prefix)) {
-                checkStartChar(generatedPassword, ruleConf);
-            }
-        }
-
-        for (String suffix : ruleConf.getSuffixesNotPermitted()) {
-            if (StringUtils.join(generatedPassword).endsWith(suffix)) {
-                checkEndChar(generatedPassword, ruleConf);
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
deleted file mode 100644
index 13a449f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
+++ /dev/null
@@ -1,33 +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.misc.security;
-
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-
-public class DelegatedAdministrationException extends RuntimeException {
-
-    private static final long serialVersionUID = 7540587364235915081L;
-
-    public DelegatedAdministrationException(final AnyTypeKind type, final Long key) {
-        super("Missing entitlement or realm administration for "
-                + (key == null
-                        ? "new " + type
-                        : type + " " + key));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
deleted file mode 100644
index 4c55513..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
+++ /dev/null
@@ -1,256 +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.misc.security;
-
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.SecretKeySpec;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.jasypt.commons.CommonUtils;
-import org.jasypt.digest.StandardStringDigester;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.crypto.bcrypt.BCrypt;
-import org.springframework.security.crypto.codec.Base64;
-
-public final class Encryptor {
-
-    private static final Logger LOG = LoggerFactory.getLogger(Encryptor.class);
-
-    private static final Map<String, Encryptor> INSTANCES = new ConcurrentHashMap<>();
-
-    private static final String DEFAULT_SECRET_KEY = "1abcdefghilmnopqrstuvz2!";
-
-    /**
-     * Default value for salted {@link StandardStringDigester#setIterations(int)}.
-     */
-    private static final int DEFAULT_SALT_ITERATIONS = 1;
-
-    /**
-     * Default value for {@link StandardStringDigester#setSaltSizeBytes(int)}.
-     */
-    private static final int DEFAULT_SALT_SIZE_BYTES = 8;
-
-    /**
-     * Default value for {@link StandardStringDigester#setInvertPositionOfPlainSaltInEncryptionResults(boolean)}.
-     */
-    private static final boolean DEFAULT_IPOPSIER = true;
-
-    /**
-     * Default value for salted {@link StandardStringDigester#setInvertPositionOfSaltInMessageBeforeDigesting(boolean)}.
-     */
-    private static final boolean DEFAULT_IPOSIMBD = true;
-
-    /**
-     * Default value for salted {@link StandardStringDigester#setUseLenientSaltSizeCheck(boolean)}.
-     */
-    private static final boolean DEFAULT_ULSSC = true;
-
-    private static String SECRET_KEY;
-
-    private static Integer SALT_ITERATIONS;
-
-    private static Integer SALT_SIZE_BYTES;
-
-    private static Boolean IPOPSIER;
-
-    private static Boolean IPOSIMBD;
-
-    private static Boolean ULSSC;
-
-    static {
-        InputStream propStream = null;
-        try {
-            propStream = Encryptor.class.getResourceAsStream("/security.properties");
-            Properties props = new Properties();
-            props.load(propStream);
-
-            SECRET_KEY = props.getProperty("secretKey");
-            SALT_ITERATIONS = Integer.valueOf(props.getProperty("digester.saltIterations"));
-            SALT_SIZE_BYTES = Integer.valueOf(props.getProperty("digester.saltSizeBytes"));
-            IPOPSIER = Boolean.valueOf(props.getProperty("digester.invertPositionOfPlainSaltInEncryptionResults"));
-            IPOSIMBD = Boolean.valueOf(props.getProperty("digester.invertPositionOfSaltInMessageBeforeDigesting"));
-            ULSSC = Boolean.valueOf(props.getProperty("digester.useLenientSaltSizeCheck"));
-        } catch (Exception e) {
-            LOG.error("Could not read security parameters", e);
-        } finally {
-            IOUtils.closeQuietly(propStream);
-        }
-
-        if (SECRET_KEY == null) {
-            SECRET_KEY = DEFAULT_SECRET_KEY;
-            LOG.debug("secretKey not found, reverting to default");
-        }
-        if (SALT_ITERATIONS == null) {
-            SALT_ITERATIONS = DEFAULT_SALT_ITERATIONS;
-            LOG.debug("digester.saltIterations not found, reverting to default");
-        }
-        if (SALT_SIZE_BYTES == null) {
-            SALT_SIZE_BYTES = DEFAULT_SALT_SIZE_BYTES;
-            LOG.debug("digester.saltSizeBytes not found, reverting to default");
-        }
-        if (IPOPSIER == null) {
-            IPOPSIER = DEFAULT_IPOPSIER;
-            LOG.debug("digester.invertPositionOfPlainSaltInEncryptionResults not found, reverting to default");
-        }
-        if (IPOSIMBD == null) {
-            IPOSIMBD = DEFAULT_IPOSIMBD;
-            LOG.debug("digester.invertPositionOfSaltInMessageBeforeDigesting not found, reverting to default");
-        }
-        if (ULSSC == null) {
-            ULSSC = DEFAULT_ULSSC;
-            LOG.debug("digester.useLenientSaltSizeCheck not found, reverting to default");
-        }
-    }
-
-    public static Encryptor getInstance() {
-        return getInstance(SECRET_KEY);
-    }
-
-    public static Encryptor getInstance(final String secretKey) {
-        String actualKey = StringUtils.isBlank(secretKey) ? DEFAULT_SECRET_KEY : secretKey;
-
-        Encryptor instance = INSTANCES.get(actualKey);
-        if (instance == null) {
-            instance = new Encryptor(actualKey);
-            INSTANCES.put(actualKey, instance);
-        }
-
-        return instance;
-    }
-
-    private SecretKeySpec keySpec;
-
-    private Encryptor(final String secretKey) {
-        String actualKey = secretKey;
-        if (actualKey.length() < 16) {
-            StringBuilder actualKeyPadding = new StringBuilder(actualKey);
-            for (int i = 0; i < 16 - actualKey.length(); i++) {
-                actualKeyPadding.append('0');
-            }
-            actualKey = actualKeyPadding.toString();
-            LOG.debug("actualKey too short, adding some random characters");
-        }
-
-        try {
-            keySpec = new SecretKeySpec(ArrayUtils.subarray(
-                    actualKey.getBytes(SyncopeConstants.DEFAULT_CHARSET), 0, 16),
-                    CipherAlgorithm.AES.getAlgorithm());
-        } catch (Exception e) {
-            LOG.error("Error during key specification", e);
-        }
-    }
-
-    public String encode(final String value, final CipherAlgorithm cipherAlgorithm)
-            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            IllegalBlockSizeException, BadPaddingException {
-
-        String encodedValue = null;
-
-        if (value != null) {
-            if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
-                final byte[] cleartext = value.getBytes(SyncopeConstants.DEFAULT_CHARSET);
-
-                final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
-                cipher.init(Cipher.ENCRYPT_MODE, keySpec);
-
-                encodedValue = new String(Base64.encode(cipher.doFinal(cleartext)));
-            } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
-                encodedValue = BCrypt.hashpw(value, BCrypt.gensalt());
-            } else {
-                encodedValue = getDigester(cipherAlgorithm).digest(value);
-            }
-        }
-
-        return encodedValue;
-    }
-
-    public boolean verify(final String value, final CipherAlgorithm cipherAlgorithm, final String encodedValue) {
-        boolean res = false;
-
-        try {
-            if (value != null) {
-                if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
-                    res = encode(value, cipherAlgorithm).equals(encodedValue);
-                } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
-                    res = BCrypt.checkpw(value, encodedValue);
-                } else {
-                    res = getDigester(cipherAlgorithm).matches(value, encodedValue);
-                }
-            }
-        } catch (Exception e) {
-            LOG.error("Could not verify encoded value", e);
-        }
-
-        return res;
-    }
-
-    public String decode(final String encodedValue, final CipherAlgorithm cipherAlgorithm)
-            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            IllegalBlockSizeException, BadPaddingException {
-
-        String value = null;
-
-        if (encodedValue != null && cipherAlgorithm == CipherAlgorithm.AES) {
-            final byte[] encoded = encodedValue.getBytes(SyncopeConstants.DEFAULT_CHARSET);
-
-            final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
-            cipher.init(Cipher.DECRYPT_MODE, keySpec);
-
-            value = new String(cipher.doFinal(Base64.decode(encoded)), SyncopeConstants.DEFAULT_CHARSET);
-        }
-
-        return value;
-    }
-
-    private StandardStringDigester getDigester(final CipherAlgorithm cipherAlgorithm) {
-        StandardStringDigester digester = new StandardStringDigester();
-
-        if (cipherAlgorithm.getAlgorithm().startsWith("S-")) {
-            // Salted ...
-            digester.setAlgorithm(cipherAlgorithm.getAlgorithm().replaceFirst("S\\-", ""));
-            digester.setIterations(SALT_ITERATIONS);
-            digester.setSaltSizeBytes(SALT_SIZE_BYTES);
-            digester.setInvertPositionOfPlainSaltInEncryptionResults(IPOPSIER);
-            digester.setInvertPositionOfSaltInMessageBeforeDigesting(IPOSIMBD);
-            digester.setUseLenientSaltSizeCheck(ULSSC);
-        } else {
-            // Not salted ...
-            digester.setAlgorithm(cipherAlgorithm.getAlgorithm());
-            digester.setIterations(1);
-            digester.setSaltSizeBytes(0);
-        }
-
-        digester.setStringOutputType(CommonUtils.STRING_OUTPUT_TYPE_HEXADECIMAL);
-        return digester;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
deleted file mode 100644
index c52d355..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
+++ /dev/null
@@ -1,80 +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.misc.security;
-
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
-
-public class MustChangePasswordFilter implements Filter {
-
-    private static final String[] ALLOWED = new String[] {
-        "/users/self", "/users/self/changePassword"
-    };
-
-    @Override
-    public void init(final FilterConfig filterConfig) throws ServletException {
-        // not used
-    }
-
-    @Override
-    public void destroy() {
-        // not used
-    }
-
-    @Override
-    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
-            throws IOException, ServletException {
-
-        if (request instanceof SecurityContextHolderAwareRequestWrapper) {
-            boolean isMustChangePassword = IterableUtils.matchesAny(
-                    SecurityContextHolder.getContext().getAuthentication().getAuthorities(),
-                    new Predicate<GrantedAuthority>() {
-
-                @Override
-                public boolean evaluate(final GrantedAuthority authority) {
-                    return StandardEntitlement.MUST_CHANGE_PASSWORD.equals(authority.getAuthority());
-                }
-            });
-
-            SecurityContextHolderAwareRequestWrapper wrapper =
-                    SecurityContextHolderAwareRequestWrapper.class.cast(request);
-            if (isMustChangePassword && "GET".equalsIgnoreCase(wrapper.getMethod())
-                    && !ArrayUtils.contains(ALLOWED, wrapper.getPathInfo())) {
-
-                throw new AccessDeniedException("Please change your password first");
-            }
-        }
-
-        chain.doFilter(request, response);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
deleted file mode 100644
index 936dae5..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ /dev/null
@@ -1,32 +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.misc.security;
-
-import java.util.List;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-
-public interface PasswordGenerator {
-
-    String generate(User user) throws InvalidPasswordRuleConf;
-
-    String generate(List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
deleted file mode 100644
index f41207b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
+++ /dev/null
@@ -1,48 +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.misc.security;
-
-import java.security.SecureRandom;
-
-import org.apache.commons.lang3.RandomStringUtils;
-
-public final class SecureRandomUtils {
-
-    private static final SecureRandom RANDOM = new SecureRandom();
-
-    public static String generateRandomPassword(final int tokenLength) {
-        return RandomStringUtils.random(tokenLength, 0, 0, true, false, null, RANDOM);
-    }
-
-    public static String generateRandomLetter() {
-        return RandomStringUtils.random(1, 0, 0, true, false, null, RANDOM);
-    }
-
-    public static String generateRandomNumber() {
-        return RandomStringUtils.random(1, 0, 0, false, true, null, RANDOM);
-    }
-
-    public static String generateRandomSpecialCharacter(final char[] characters) {
-        return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
-    }
-
-    private SecureRandomUtils() {
-        // private constructor for static utility class
-    }
-}


[04/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..a589416
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..92dd5eb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.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.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/28569df5/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
new file mode 100644
index 0000000..703bc49
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -0,0 +1,269 @@
+/*
+ * 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.utils;
+
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+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;
+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.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedByteArray;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+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;
+
+@Component
+public class ConnObjectUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtils.class);
+
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+    @Autowired
+    private TemplateUtils templateUtils;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private PasswordGenerator passwordGenerator;
+
+    @Autowired
+    private MappingManager mappingManager;
+
+    /**
+     * Extract password value from passed value (if instance of GuardedString or GuardedByteArray).
+     *
+     * @param pwd received from the underlying connector
+     * @return password value
+     */
+    public static String getPassword(final Object pwd) {
+        final StringBuilder result = new StringBuilder();
+
+        if (pwd instanceof GuardedString) {
+            ((GuardedString) pwd).access(new GuardedString.Accessor() {
+
+                @Override
+                public void access(final char[] clearChars) {
+                    result.append(clearChars);
+                }
+            });
+        } else if (pwd instanceof GuardedByteArray) {
+            ((GuardedByteArray) pwd).access(new GuardedByteArray.Accessor() {
+
+                @Override
+                public void access(final byte[] clearBytes) {
+                    result.append(new String(clearBytes));
+                }
+            });
+        } else if (pwd instanceof String) {
+            result.append((String) pwd);
+        } else {
+            result.append(pwd.toString());
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
+     *
+     * @param obj connector object
+     * @param syncTask synchronization task
+     * @param provision provision information
+     * @param anyUtils utils
+     * @param <T> any object
+     * @return UserTO for the user to be created
+     */
+    @Transactional(readOnly = true)
+    public <T extends AnyTO> T getAnyTO(
+            final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+
+        T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+
+        // (for users) if password was not set above, generate
+        if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
+            final UserTO userTO = (UserTO) anyTO;
+
+            List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+
+            Realm realm = realmDAO.find(userTO.getRealm());
+            if (realm != null) {
+                for (Realm ancestor : realmDAO.findAncestors(realm)) {
+                    if (ancestor.getPasswordPolicy() != null) {
+                        ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
+                    }
+                }
+            }
+
+            for (String resName : userTO.getResources()) {
+                ExternalResource resource = resourceDAO.find(resName);
+                if (resource != null && resource.getPasswordPolicy() != null) {
+                    ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
+                }
+            }
+
+            String password;
+            try {
+                password = passwordGenerator.generate(ruleConfs);
+            } catch (InvalidPasswordRuleConf e) {
+                LOG.error("Could not generate policy-compliant random password for {}", userTO, e);
+
+                password = SecureRandomUtils.generateRandomPassword(16);
+            }
+            userTO.setPassword(password);
+        }
+
+        return anyTO;
+    }
+
+    /**
+     * Build {@link AnyPatch} out of connector object attributes and schema mapping.
+     *
+     * @param key any object to be updated
+     * @param obj connector object
+     * @param original any object to get diff from
+     * @param syncTask synchronization task
+     * @param provision provision information
+     * @param anyUtils utils
+     * @param <T> any object
+     * @return modifications for the any object to be updated
+     */
+    @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) {
+
+        AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+        updated.setKey(key);
+
+        if (null != anyUtils.getAnyTypeKind()) {
+            switch (anyUtils.getAnyTypeKind()) {
+                case USER:
+                    // update password if and only if password is really changed
+                    User user = userDAO.authFind(key);
+                    if (StringUtils.isBlank(((UserTO) updated).getPassword())
+                            || ENCRYPTOR.verify(((UserTO) updated).getPassword(),
+                                    user.getCipherAlgorithm(), user.getPassword())) {
+
+                        ((UserTO) updated).setPassword(null);
+                    }
+                    return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
+
+                case GROUP:
+                    return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
+
+                case ANY_OBJECT:
+                    return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
+
+                default:
+            }
+        }
+
+        return null;
+    }
+
+    private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
+            final SyncTask syncTask, 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)) {
+            mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
+        }
+
+        // 2. add data from defined template (if any)
+        templateUtils.apply(anyTO, syncTask.getTemplate(provision.getAnyType()));
+
+        return anyTO;
+    }
+
+    /**
+     * Get connector object TO from a connector object.
+     *
+     * @param connObject connector object.
+     * @return connector object TO.
+     */
+    public ConnObjectTO getConnObjectTO(final ConnectorObject connObject) {
+        final ConnObjectTO connObjectTO = new ConnObjectTO();
+
+        if (connObject != null) {
+            for (Attribute attr : connObject.getAttributes()) {
+                AttrTO attrTO = new AttrTO();
+                attrTO.setSchema(attr.getName());
+
+                if (attr.getValue() != null) {
+                    for (Object value : attr.getValue()) {
+                        if (value != null) {
+                            if (value instanceof GuardedString || value instanceof GuardedByteArray) {
+                                attrTO.getValues().add(getPassword(value));
+                            } else if (value instanceof byte[]) {
+                                attrTO.getValues().add(Base64.encode((byte[]) value));
+                            } else {
+                                attrTO.getValues().add(value.toString());
+                            }
+                        }
+                    }
+                }
+
+                connObjectTO.getPlainAttrs().add(attrTO);
+            }
+        }
+
+        return connObjectTO;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
new file mode 100644
index 0000000..31342ec
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
@@ -0,0 +1,224 @@
+/*
+ * 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.utils;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+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.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class TemplateUtils {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    private AttrTO evaluateAttr(final AnyTO anyTO, final AttrTO template) {
+        AttrTO result = new AttrTO();
+        result.setSchema(template.getSchema());
+
+        if (template.getValues() != null && !template.getValues().isEmpty()) {
+            for (String value : template.getValues()) {
+                String evaluated = JexlUtils.evaluate(value, anyTO);
+                if (StringUtils.isNotBlank(evaluated)) {
+                    result.getValues().add(evaluated);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private void fill(final AnyTO anyTO, final AnyTO template) {
+        if (template.getRealm() != null) {
+            anyTO.setRealm(template.getRealm());
+        }
+
+        Map<String, AttrTO> currentAttrMap = anyTO.getPlainAttrMap();
+        for (AttrTO templatePlainAttr : template.getPlainAttrs()) {
+            if (!templatePlainAttr.getValues().isEmpty()
+                    && (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
+                    || currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
+
+                anyTO.getPlainAttrs().add(evaluateAttr(anyTO, templatePlainAttr));
+            }
+        }
+
+        currentAttrMap = anyTO.getDerAttrMap();
+        for (AttrTO templateDerAttr : template.getDerAttrs()) {
+            if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
+                anyTO.getDerAttrs().add(templateDerAttr);
+            }
+        }
+
+        currentAttrMap = anyTO.getVirAttrMap();
+        for (AttrTO templateVirAttr : template.getVirAttrs()) {
+            if (!templateVirAttr.getValues().isEmpty()
+                    && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
+                    || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
+
+                anyTO.getVirAttrs().add(evaluateAttr(anyTO, templateVirAttr));
+            }
+        }
+
+        for (String resource : template.getResources()) {
+            anyTO.getResources().add(resource);
+        }
+
+        anyTO.getAuxClasses().addAll(template.getAuxClasses());
+    }
+
+    private void fillRelationships(final Map<Pair<String, Long>, RelationshipTO> anyRelMap,
+            final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
+
+        for (RelationshipTO memb : templateRels) {
+            if (!anyRelMap.containsKey(Pair.of(memb.getRightType(), memb.getRightKey()))) {
+                anyRels.add(memb);
+            }
+        }
+    }
+
+    private void fillMemberships(final Map<Long, MembershipTO> anyMembMap,
+            final List<MembershipTO> anyMembs, final List<MembershipTO> templateMembs) {
+
+        for (MembershipTO memb : templateMembs) {
+            if (!anyMembMap.containsKey(memb.getRightKey())) {
+                anyMembs.add(memb);
+            }
+        }
+    }
+
+    @Transactional(readOnly = true)
+    public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
+        if (anyTemplate != null) {
+            AnyTO template = anyTemplate.get();
+            fill(anyTO, template);
+
+            if (template instanceof AnyObjectTO) {
+                fillRelationships(((AnyObjectTO) anyTO).getRelationshipMap(),
+                        ((AnyObjectTO) anyTO).getRelationships(), ((AnyObjectTO) template).getRelationships());
+                fillMemberships(((AnyObjectTO) anyTO).getMembershipMap(),
+                        ((AnyObjectTO) anyTO).getMemberships(), ((AnyObjectTO) template).getMemberships());
+            } else if (template instanceof UserTO) {
+                if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
+                    String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
+                    if (StringUtils.isNotBlank(evaluated)) {
+                        ((UserTO) anyTO).setUsername(evaluated);
+                    }
+                }
+
+                if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
+                    String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO);
+                    if (StringUtils.isNotBlank(evaluated)) {
+                        ((UserTO) anyTO).setPassword(evaluated);
+                    }
+                }
+
+                fillRelationships(((UserTO) anyTO).getRelationshipMap(),
+                        ((UserTO) anyTO).getRelationships(), ((UserTO) template).getRelationships());
+                fillMemberships(((UserTO) anyTO).getMembershipMap(),
+                        ((UserTO) anyTO).getMemberships(), ((UserTO) template).getMemberships());
+            } else if (template instanceof GroupTO) {
+                if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
+                    String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
+                    if (StringUtils.isNotBlank(evaluated)) {
+                        ((GroupTO) anyTO).setName(evaluated);
+                    }
+                }
+
+                if (((GroupTO) template).getUserOwner() != null) {
+                    final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
+                    if (userOwner != null) {
+                        ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
+                    }
+                }
+                if (((GroupTO) template).getGroupOwner() != null) {
+                    final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
+                    if (groupOwner != null) {
+                        ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
+                    }
+                }
+            }
+        }
+    }
+
+    public void check(final Map<String, AnyTO> templates, final ClientExceptionType clientExceptionType) {
+        SyncopeClientException sce = SyncopeClientException.build(clientExceptionType);
+
+        for (Map.Entry<String, AnyTO> entry : templates.entrySet()) {
+            for (AttrTO attrTO : entry.getValue().getPlainAttrs()) {
+                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+                }
+            }
+
+            for (AttrTO attrTO : entry.getValue().getVirAttrs()) {
+                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+                }
+            }
+
+            if (entry.getValue() instanceof UserTO) {
+                UserTO template = (UserTO) entry.getValue();
+                if (StringUtils.isNotBlank(template.getUsername())
+                        && !JexlUtils.isExpressionValid(template.getUsername())) {
+
+                    sce.getElements().add("Invalid JEXL: " + template.getUsername());
+                }
+                if (StringUtils.isNotBlank(template.getPassword())
+                        && !JexlUtils.isExpressionValid(template.getPassword())) {
+
+                    sce.getElements().add("Invalid JEXL: " + template.getPassword());
+                }
+            } else if (entry.getValue() instanceof GroupTO) {
+                GroupTO template = (GroupTO) entry.getValue();
+                if (StringUtils.isNotBlank(template.getName())
+                        && !JexlUtils.isExpressionValid(template.getName())) {
+
+                    sce.getElements().add("Invalid JEXL: " + template.getName());
+                }
+            }
+        }
+
+        if (!sce.isEmpty()) {
+            throw sce;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
index 1193e16..e26f238 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
@@ -27,7 +27,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     "classpath:persistenceTest.xml",
     "classpath:provisioningContext.xml",
     "classpath:workflowContext.xml",
-    "classpath:utilsContext.xml",
     "classpath:provisioningTest.xml"
 })
 public abstract class AbstractTest {

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
index 205aa2f..1b2e060 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
@@ -24,7 +24,7 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
index fe55f8e..b87a6a9 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
@@ -35,7 +35,7 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
index 91486ab..820b8d2 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.java;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-import org.apache.syncope.core.misc.utils.MappingUtils;
 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.UserDAO;
@@ -58,12 +57,12 @@ public class MappingTest extends AbstractTest {
         User user = userDAO.find("rossini");
         assertNotNull(user);
 
-        Name name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        Name name = MappingManagerImpl.evaluateNAME(user, provision, user.getUsername());
         assertEquals("uid=rossini,ou=people,o=isp", name.getNameValue());
 
         provision.getMapping().setConnObjectLink("'uid=' + username + ',o=' + realm + ',ou=people,o=isp'");
 
-        name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        name = MappingManagerImpl.evaluateNAME(user, provision, user.getUsername());
         assertEquals("uid=rossini,o=even,ou=people,o=isp", name.getNameValue());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
index 1ae087a..d0bc946 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
@@ -24,7 +24,7 @@ import javax.ws.rs.container.ContainerResponseContext;
 import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.ext.Provider;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 
 /**
  * Adds the domain header to all responses.

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index 42cbfda..12e1d28 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -45,7 +45,7 @@ import org.apache.syncope.common.lib.to.ErrorTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
index f767c19..e6c5c39 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.rest.cxf;
 
 import javax.servlet.ServletRequestEvent;
 import javax.servlet.ServletRequestListener;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.impl.api.local.ThreadClassLoaderManager;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
index eec8927..453f074 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
@@ -42,7 +42,7 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.search.SearchCondVisitor;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/pom.xml
----------------------------------------------------------------------
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
new file mode 100644
index 0000000..c912488
--- /dev/null
+++ b/core/spring/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope</groupId>
+    <artifactId>syncope-core</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Core Spring</name>
+  <description>Apache Syncope Core Misc</description>
+  <groupId>org.apache.syncope.core</groupId>
+  <artifactId>syncope-core-spring</artifactId>
+  <packaging>jar</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+  </properties>
+
+  <dependencies>    
+    <dependency> 
+      <groupId>javax.servlet</groupId> 
+      <artifactId>javax.servlet-api</artifactId> 
+      <scope>provided</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jasypt</groupId>
+      <artifactId>jasypt</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.security</groupId>
+      <artifactId>spring-security-web</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-tx</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-provisioning-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>        
+    <dependency>
+      <groupId>org.apache.syncope.common</groupId>
+      <artifactId>syncope-common-rest-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <!-- TEST -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
new file mode 100644
index 0000000..a1ad7f1
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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.spring;
+
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ApplicationContextProvider implements ApplicationContextAware {
+
+    private static ConfigurableApplicationContext CTX;
+
+    private static DefaultListableBeanFactory BEAN_FACTORY;
+
+    public static ConfigurableApplicationContext getApplicationContext() {
+        return CTX;
+    }
+
+    public static DefaultListableBeanFactory getBeanFactory() {
+        return BEAN_FACTORY == null
+                ? CTX == null
+                        ? null
+                        : (DefaultListableBeanFactory) CTX.getBeanFactory()
+                : BEAN_FACTORY;
+    }
+
+    public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
+        BEAN_FACTORY = beanFactory;
+    }
+
+    /**
+     * Wiring the ApplicationContext into a static method.
+     *
+     * @param ctx Spring application context
+     */
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) {
+        CTX = (ConfigurableApplicationContext) ctx;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
new file mode 100644
index 0000000..980b022
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
@@ -0,0 +1,193 @@
+/*
+ * 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.spring;
+
+import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
+import static org.springframework.beans.BeanUtils.getPropertyDescriptors;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Overrides Spring's BeanUtils not using collection setters but instead getters + addAll() / putAll(),
+ * in a JAXB friendly way.
+ *
+ * Refer to <a href="https://issues.apache.org/jira/browse/SYNCOPE-246">SYNCOPE-246</a> for more information.
+ *
+ * @see org.springframework.beans.BeanUtils
+ */
+public final class BeanUtils {
+
+    private BeanUtils() {
+        // Empty private constructor for static utility classes
+    }
+
+    /**
+     * Copy the property values of the given source bean into the target bean.
+     * <p>
+     * Note: The source and target classes do not have to match or even be derived
+     * from each other, as long as the properties match. Any bean properties that the
+     * source bean exposes but the target bean does not will silently be ignored.
+     * </p><p>
+     * This is just a convenience method. For more complex transfer needs,
+     * consider using a full BeanWrapper.
+     * </p>
+     *
+     * @param source the source bean
+     * @param target the target bean
+     * @see org.springframework.beans.BeanWrapper
+     */
+    public static void copyProperties(final Object source, final Object target) {
+        copyProperties(source, target, null, (String[]) null);
+    }
+
+    /**
+     * Copy the property values of the given source bean into the given target bean,
+     * only setting properties defined in the given "editable" class (or interface).
+     * <p>
+     * Note: The source and target classes do not have to match or even be derived
+     * from each other, as long as the properties match. Any bean properties that the
+     * source bean exposes but the target bean does not will silently be ignored.
+     * </p><p>
+     * This is just a convenience method. For more complex transfer needs,
+     * consider using a full BeanWrapper.
+     * </p>
+     *
+     * @param source the source bean
+     * @param target the target bean
+     * @param editable the class (or interface) to restrict property setting to
+     * @see org.springframework.beans.BeanWrapper
+     */
+    public static void copyProperties(final Object source, final Object target, final Class<?> editable) {
+        copyProperties(source, target, editable, (String[]) null);
+    }
+
+    /**
+     * Copy the property values of the given source bean into the given target bean,
+     * ignoring the given "ignoreProperties".
+     * <p>
+     * Note: The source and target classes do not have to match or even be derived
+     * from each other, as long as the properties match. Any bean properties that the
+     * source bean exposes but the target bean does not will silently be ignored.
+     * </p><p>
+     * This is just a convenience method. For more complex transfer needs,
+     * consider using a full BeanWrapper.
+     * </p>
+     *
+     * @param source the source bean
+     * @param target the target bean
+     * @param ignoreProperties array of property names to ignore
+     * @see org.springframework.beans.BeanWrapper
+     */
+    public static void copyProperties(final Object source, final Object target, final String... ignoreProperties) {
+        copyProperties(source, target, null, ignoreProperties);
+    }
+
+    /**
+     * Copy the property values of the given source bean into the given target bean.
+     * <p>
+     * Note: The source and target classes do not have to match or even be derived
+     * from each other, as long as the properties match. Any bean properties that the
+     * source bean exposes but the target bean does not will silently be ignored.
+     * </p>
+     *
+     * @param source the source bean
+     * @param target the target bean
+     * @param editable the class (or interface) to restrict property setting to
+     * @param ignoreProperties array of property names to ignore
+     * @see org.springframework.beans.BeanWrapper
+     */
+    @SuppressWarnings("unchecked")
+    private static void copyProperties(
+            final Object source, final Object target, final Class<?> editable, final String... ignoreProperties) {
+
+        Assert.notNull(source, "Source must not be null");
+        Assert.notNull(target, "Target must not be null");
+
+        Class<?> actualEditable = target.getClass();
+        if (editable != null) {
+            if (!editable.isInstance(target)) {
+                throw new IllegalArgumentException("Target class [" + target.getClass().getName()
+                        + "] not assignable to Editable class [" + editable.getName() + "]");
+            }
+            actualEditable = editable;
+        }
+        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
+        List<String> ignoreList = (ignoreProperties == null)
+                ? Collections.<String>emptyList() : Arrays.asList(ignoreProperties);
+
+        for (PropertyDescriptor targetPd : targetPds) {
+            if (ignoreProperties == null || (!ignoreList.contains(targetPd.getName()))) {
+                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
+                if (sourcePd != null) {
+                    Method readMethod = sourcePd.getReadMethod();
+                    if (readMethod != null) {
+                        Method writeMethod = targetPd.getWriteMethod();
+
+                        try {
+                            // Diverts from Spring's BeanUtils: if no write method is found and property is collection,
+                            // try to use addAll() / putAll().
+                            if (writeMethod == null) {
+                                Object value = readMethod.invoke(source);
+                                Method targetReadMethod = targetPd.getReadMethod();
+                                if (targetReadMethod != null) {
+                                    if (!Modifier.isPublic(targetReadMethod.getDeclaringClass().getModifiers())) {
+                                        targetReadMethod.setAccessible(true);
+                                    }
+                                    Object destValue = targetReadMethod.invoke(target);
+
+                                    if (value instanceof Collection && destValue instanceof Collection) {
+                                        ((Collection) destValue).clear();
+                                        ((Collection) destValue).addAll((Collection) value);
+                                    } else if (value instanceof Map && destValue instanceof Map) {
+                                        ((Map) destValue).clear();
+                                        ((Map) destValue).putAll((Map) value);
+                                    }
+                                }
+                            } else if (ClassUtils.isAssignable(
+                                    writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
+
+                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
+                                    readMethod.setAccessible(true);
+                                }
+                                Object value = readMethod.invoke(source);
+                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
+                                    writeMethod.setAccessible(true);
+                                }
+                                writeMethod.invoke(target, value);
+                            }
+                        } catch (Throwable ex) {
+                            throw new FatalBeanException(
+                                    "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
new file mode 100644
index 0000000..2e197ea
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * 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.spring;
+
+import javax.servlet.ServletException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.PriorityOrdered;
+import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
+
+/**
+ * Removes the limitation of having Spring security roles to be prefixed with 'ROLE_'.
+ */
+public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
+
+    @Override
+    public Object postProcessAfterInitialization(final Object bean, final String beanName) {
+        if (bean instanceof DefaultMethodSecurityExpressionHandler) {
+            ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
+        }
+        if (bean instanceof DefaultWebSecurityExpressionHandler) {
+            ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
+        }
+        if (bean instanceof SecurityContextHolderAwareRequestFilter) {
+            SecurityContextHolderAwareRequestFilter filter = (SecurityContextHolderAwareRequestFilter) bean;
+            filter.setRolePrefix(StringUtils.EMPTY);
+            try {
+                filter.afterPropertiesSet();
+            } catch (ServletException e) {
+                throw new FatalBeanException(e.getMessage(), e);
+            }
+        }
+
+        return bean;
+    }
+
+    @Override
+    public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
+        return bean;
+    }
+
+    @Override
+    public int getOrder() {
+        return PriorityOrdered.HIGHEST_PRECEDENCE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
new file mode 100644
index 0000000..846b575
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
@@ -0,0 +1,82 @@
+/*
+ * 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.spring;
+
+import java.io.IOException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class ResourceWithFallbackLoader implements ResourceLoaderAware, ResourcePatternResolver {
+
+    private ResourcePatternResolver resolver;
+
+    private String primary;
+
+    private String fallback;
+
+    @Override
+    public void setResourceLoader(final ResourceLoader resourceLoader) {
+        this.resolver = (ResourcePatternResolver) resourceLoader;
+    }
+
+    public void setPrimary(final String primary) {
+        this.primary = primary;
+    }
+
+    public void setFallback(final String fallback) {
+        this.fallback = fallback;
+    }
+
+    @Override
+    public Resource getResource(final String location) {
+        Resource resource = resolver.getResource(primary + location);
+        if (!resource.exists()) {
+            resource = resolver.getResource(fallback + location);
+        }
+
+        return resource;
+    }
+
+    public Resource getResource() {
+        return getResource(StringUtils.EMPTY);
+    }
+
+    @Override
+    public Resource[] getResources(final String locationPattern) throws IOException {
+        Resource[] resources = resolver.getResources(primary + locationPattern);
+        if (ArrayUtils.isEmpty(resources)) {
+            resources = resolver.getResources(fallback + locationPattern);
+        }
+
+        return resources;
+    }
+
+    public Resource[] getResources() throws IOException {
+        return getResources(StringUtils.EMPTY);
+    }
+
+    @Override
+    public ClassLoader getClassLoader() {
+        return resolver.getClassLoader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
new file mode 100644
index 0000000..9bc03f7
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
@@ -0,0 +1,126 @@
+/*
+ * 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.spring.security;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+public final class AuthContextUtils {
+
+    public interface Executable<T> {
+
+        T exec();
+    }
+
+    public static String getUsername() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
+    }
+
+    public static void updateUsername(final String newUsername) {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
+                new User(newUsername, "FAKE_PASSWORD", auth.getAuthorities()),
+                auth.getCredentials(), auth.getAuthorities());
+        newAuth.setDetails(auth.getDetails());
+        SecurityContextHolder.getContext().setAuthentication(newAuth);
+    }
+
+    public static Map<String, Set<String>> getAuthorizations() {
+        Map<String, Set<String>> result = null;
+
+        SecurityContext ctx = SecurityContextHolder.getContext();
+        if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
+            result = new HashMap<>();
+            for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
+                if (authority instanceof SyncopeGrantedAuthority) {
+                    result.put(
+                            SyncopeGrantedAuthority.class.cast(authority).getAuthority(),
+                            SyncopeGrantedAuthority.class.cast(authority).getRealms());
+                }
+            }
+        }
+
+        return MapUtils.emptyIfNull(result);
+    }
+
+    public static String getDomain() {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+        String domainKey = auth != null && auth.getDetails() instanceof SyncopeAuthenticationDetails
+                ? SyncopeAuthenticationDetails.class.cast(auth.getDetails()).getDomain()
+                : null;
+        if (StringUtils.isBlank(domainKey)) {
+            domainKey = SyncopeConstants.MASTER_DOMAIN;
+        }
+
+        return domainKey;
+    }
+
+    private static void setFakeAuth(final String domain) {
+        List<GrantedAuthority> authorities = CollectionUtils.collect(EntitlementsHolder.getInstance().getValues(),
+                new Transformer<String, GrantedAuthority>() {
+
+            @Override
+            public GrantedAuthority transform(final String entitlement) {
+                return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+            }
+        }, new ArrayList<GrantedAuthority>());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
+                        "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails(domain));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    public static <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
+        SecurityContext ctx = SecurityContextHolder.getContext();
+        setFakeAuth(domainKey);
+        try {
+            return executable.exec();
+        } finally {
+            SecurityContextHolder.clearContext();
+            SecurityContextHolder.setContext(ctx);
+        }
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private AuthContextUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
new file mode 100644
index 0000000..146eea3
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -0,0 +1,319 @@
+/*
+ * 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.spring.security;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
+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.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Domain-sensible (via {@code @Transactional} access to authentication / authorization data.
+ *
+ * @see SyncopeAuthenticationProvider
+ * @see SyncopeAuthenticationDetails
+ */
+public class AuthDataAccessor {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
+
+    protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
+    @Resource(name = "anonymousUser")
+    protected String anonymousUser;
+
+    @Autowired
+    protected DomainDAO domainDAO;
+
+    @Autowired
+    protected ConfDAO confDAO;
+
+    @Autowired
+    protected RealmDAO realmDAO;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    protected ConnectorFactory connFactory;
+
+    @Autowired
+    protected AuditManager auditManager;
+
+    @Autowired
+    protected MappingManager mappingManager;
+
+    @Transactional(readOnly = true)
+    public Domain findDomain(final String key) {
+        Domain domain = domainDAO.find(key);
+        if (domain == null) {
+            throw new AuthenticationServiceException("Could not find domain " + key);
+        }
+        return domain;
+    }
+
+    /**
+     * Attempts to authenticate the given credentials against internal storage and pass-through resources (if
+     * configured): the first succeeding causes global success.
+     *
+     * @param authentication given credentials
+     * @return {@code null} if no matching user was found, authentication result otherwise
+     */
+    @Transactional(noRollbackFor = DisabledException.class)
+    public Pair<Long, Boolean> authenticate(final Authentication authentication) {
+        Long key = null;
+        Boolean authenticated = null;
+
+        User user = userDAO.find(authentication.getName());
+        if (user != null) {
+            key = user.getKey();
+            authenticated = false;
+
+            if (user.isSuspended() != null && user.isSuspended()) {
+                throw new DisabledException("User " + user.getUsername() + " is suspended");
+            }
+
+            CPlainAttr authStatuses = confDAO.find("authentication.statuses");
+            if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
+                throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
+            }
+
+            boolean userModified = false;
+            authenticated = authenticate(user, authentication.getCredentials().toString());
+            if (authenticated) {
+                if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
+                    user.setLastLoginDate(new Date());
+                    userModified = true;
+                }
+
+                if (user.getFailedLogins() != 0) {
+                    user.setFailedLogins(0);
+                    userModified = true;
+                }
+
+            } else {
+                user.setFailedLogins(user.getFailedLogins() + 1);
+                userModified = true;
+            }
+
+            if (userModified) {
+                userDAO.save(user);
+            }
+        }
+
+        return ImmutablePair.of(key, authenticated);
+    }
+
+    protected boolean authenticate(final User user, final String password) {
+        boolean authenticated = ENCRYPTOR.verify(password, user.getCipherAlgorithm(), user.getPassword());
+        LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
+
+        for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
+                itor.hasNext() && !authenticated;) {
+
+            ExternalResource resource = itor.next();
+            String connObjectKey = null;
+            try {
+                connObjectKey = mappingManager.getConnObjectKeyValue(
+                        user, resource.getProvision(anyTypeDAO.findUser()));
+                Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
+                if (uid != null) {
+                    authenticated = true;
+                }
+            } catch (Exception e) {
+                LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
+            }
+            LOG.debug("{} authenticated on {} as {}: {}",
+                    user.getUsername(), resource.getKey(), connObjectKey, authenticated);
+        }
+
+        return authenticated;
+    }
+
+    protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
+        Set<? extends ExternalResource> result = null;
+
+        // 1. look for assigned resources, pick the ones whose account policy has authentication resources
+        for (ExternalResource resource : userDAO.findAllResources(user)) {
+            if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = resource.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(resource.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        // 2. look for realms, pick the ones whose account policy has authentication resources
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = realm.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(realm.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        return SetUtils.emptyIfNull(result);
+    }
+
+    @Transactional(readOnly = true)
+    public void audit(
+            final AuditElements.EventCategoryType type,
+            final String category,
+            final String subcategory,
+            final String event,
+            final AuditElements.Result result,
+            final Object before,
+            final Object output,
+            final Object... input) {
+
+        auditManager.audit(type, category, subcategory, event, result, before, output, input);
+    }
+
+    @Transactional
+    public Set<SyncopeGrantedAuthority> load(final String username) {
+        final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
+        if (anonymousUser.equals(username)) {
+            authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.ANONYMOUS));
+        } else if (adminUser.equals(username)) {
+            CollectionUtils.collect(
+                    EntitlementsHolder.getInstance().getValues(),
+                    new Transformer<String, SyncopeGrantedAuthority>() {
+
+                @Override
+                public SyncopeGrantedAuthority transform(final String entitlement) {
+                    return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                }
+            }, authorities);
+        } else {
+            User user = userDAO.find(username);
+            if (user == null) {
+                throw new UsernameNotFoundException("Could not find any user with id " + username);
+            }
+
+            if (user.isMustChangePassword()) {
+                authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.MUST_CHANGE_PASSWORD));
+            } else {
+                final Map<String, Set<String>> entForRealms = new HashMap<>();
+
+                // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
+                // statically and dynamically
+                for (final Role role : userDAO.findAllRoles(user)) {
+                    IterableUtils.forEach(role.getEntitlements(), new Closure<String>() {
+
+                        @Override
+                        public void execute(final String entitlement) {
+                            Set<String> realms = entForRealms.get(entitlement);
+                            if (realms == null) {
+                                realms = new HashSet<>();
+                                entForRealms.put(entitlement, realms);
+                            }
+
+                            CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
+
+                                @Override
+                                public String transform(final Realm realm) {
+                                    return realm.getFullPath();
+                                }
+                            }, realms);
+                        }
+                    });
+                }
+
+                // Give group entitlements for owned groups
+                for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
+                    for (String entitlement : Arrays.asList(
+                            StandardEntitlement.GROUP_READ,
+                            StandardEntitlement.GROUP_UPDATE,
+                            StandardEntitlement.GROUP_DELETE)) {
+
+                        Set<String> realms = entForRealms.get(entitlement);
+                        if (realms == null) {
+                            realms = new HashSet<>();
+                            entForRealms.put(entitlement, realms);
+                        }
+
+                        realms.add(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
+                    }
+                }
+
+                // Finally normalize realms for each given entitlement and generate authorities
+                for (Map.Entry<String, Set<String>> entry : entForRealms.entrySet()) {
+                    SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entry.getKey());
+                    authority.addRealms(RealmUtils.normalize(entry.getValue()));
+                    authorities.add(authority);
+                }
+            }
+        }
+
+        return authorities;
+    }
+}


[12/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 ae07439..6c00347 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
@@ -50,7 +50,7 @@ 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.sync.SyncActions;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 0787b63..02f9529 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -1015,7 +1015,7 @@ under the License.
                        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"
                        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.sync.LDAPMembershipSyncActions"/>
+  <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"
         unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
index c7e7a9b..506c068 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
@@ -28,11 +28,11 @@ under the License.
                            http://www.springframework.org/schema/util
                            http://www.springframework.org/schema/util/spring-util.xsd">
   
-  <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="TwoContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
     <property name="fallback" value="classpath:domains/TwoContent.xml"/>
   </bean>
-  <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="TwoProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
     <property name="fallback" value="classpath:domains/Two.properties"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/resources/persistenceTest.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
index 2874cac..b4d7125 100644
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ b/core/persistence-jpa/src/test/resources/persistenceTest.xml
@@ -37,7 +37,7 @@ under the License.
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
   
-  <bean class="org.apache.syncope.core.misc.spring.ApplicationContextProvider"/>
+  <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/>
 
   <bean id="adminUser" class="java.lang.String">
     <constructor-arg value="${adminUser}"/>
@@ -46,10 +46,9 @@ under the License.
     <constructor-arg value="${anonymousUser}"/>
   </bean>
   
-  <context:component-scan base-package="org.apache.syncope.core.misc.policy"/>
-  <context:component-scan base-package="org.apache.syncope.core.misc.security"/>
+  <context:component-scan base-package="org.apache.syncope.core.spring.security"/>
 
-  <bean class="org.apache.syncope.core.misc.security.DefaultPasswordGenerator"/>
+  <bean class="org.apache.syncope.core.spring.security.DefaultPasswordGenerator"/>
 
   <import resource="persistenceContext.xml"/>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 35a4958..2dd6e3f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -79,7 +79,7 @@ under the License.
   <modules>
     <module>persistence-api</module>
     <module>persistence-jpa</module>
-    <module>misc</module>
+    <module>spring</module>
     <module>provisioning-api</module>
     <module>provisioning-java</module>
     <module>workflow-api</module>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-api/pom.xml b/core/provisioning-api/pom.xml
index 8bc9432..856a932 100644
--- a/core/provisioning-api/pom.xml
+++ b/core/provisioning-api/pom.xml
@@ -39,6 +39,19 @@ under the License.
 
   <dependencies>
     <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-afterburner</artifactId>
+    </dependency>
+    
+    <dependency>
       <groupId>org.quartz-scheduler</groupId>
       <artifactId>quartz</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
new file mode 100644
index 0000000..58b0303
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.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.core.provisioning.api;
+
+import org.apache.syncope.common.lib.types.AuditElements;
+
+public interface AuditManager {
+
+    void audit(
+            AuditElements.EventCategoryType type,
+            String category,
+            String subcategory,
+            String event,
+            AuditElements.Result result,
+            Object before,
+            Object output,
+            Object... input);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
deleted file mode 100644
index 55216ae..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api;
-
-import org.apache.syncope.common.lib.to.ConnPoolConfTO;
-import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
-import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
-
-public final class ConnPoolConfUtils {
-
-    public static ConnPoolConf getConnPoolConf(final ConnPoolConfTO cpcto, final ConnPoolConf cpc) {
-        ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
-
-        cpc.setMaxIdle(cpcto.getMaxIdle() == null ? opc.getMaxIdle() : cpcto.getMaxIdle());
-        cpc.setMaxObjects(cpcto.getMaxObjects() == null ? opc.getMaxObjects() : cpcto.getMaxObjects());
-        cpc.setMaxWait(cpcto.getMaxWait() == null ? opc.getMaxWait() : cpcto.getMaxWait());
-        cpc.setMinEvictableIdleTimeMillis(cpcto.getMinEvictableIdleTimeMillis() == null
-                ? opc.getMinEvictableIdleTimeMillis() : cpcto.getMinEvictableIdleTimeMillis());
-        cpc.setMinIdle(cpcto.getMinIdle() == null ? opc.getMinIdle() : cpcto.getMinIdle());
-
-        return cpc;
-    }
-
-    public static ObjectPoolConfiguration getObjectPoolConfiguration(final ConnPoolConf cpc) {
-        ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
-        updateObjectPoolConfiguration(opc, cpc);
-        return opc;
-    }
-
-    public static void updateObjectPoolConfiguration(
-            final ObjectPoolConfiguration opc, final ConnPoolConf cpc) {
-
-        if (cpc.getMaxIdle() != null) {
-            opc.setMaxIdle(cpc.getMaxIdle());
-        }
-        if (cpc.getMaxObjects() != null) {
-            opc.setMaxObjects(cpc.getMaxObjects());
-        }
-        if (cpc.getMaxWait() != null) {
-            opc.setMaxWait(cpc.getMaxWait());
-        }
-        if (cpc.getMinEvictableIdleTimeMillis() != null) {
-            opc.setMinEvictableIdleTimeMillis(cpc.getMinEvictableIdleTimeMillis());
-        }
-        if (cpc.getMinIdle() != null) {
-            opc.setMinIdle(cpc.getMinIdle());
-        }
-    }
-
-    private ConnPoolConfUtils() {
-        // empty constructor for static utility class
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 7aed2ca..b637508 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.sync.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
 
 /**
  * Entry point for making requests on underlying connector bundles.

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
new file mode 100644
index 0000000..d67362f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * License); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.syncope.common.lib.types.AnyEntitlement;
+
+public final class EntitlementsHolder {
+
+    private static final Object MONITOR = new Object();
+
+    private static EntitlementsHolder INSTANCE;
+
+    public static EntitlementsHolder getInstance() {
+        synchronized (MONITOR) {
+            if (INSTANCE == null) {
+                INSTANCE = new EntitlementsHolder();
+            }
+        }
+        return INSTANCE;
+    }
+
+    private final Set<String> values = Collections.synchronizedSet(new HashSet<String>());
+
+    private EntitlementsHolder() {
+        // private constructor for singleton
+    }
+
+    public void init(final Collection<String> values) {
+        this.values.addAll(values);
+    }
+
+    public String getFor(final String anyTypeKey, final AnyEntitlement operation) {
+        return anyTypeKey + "_" + operation.name();
+    }
+
+    public void addFor(final String anyType) {
+        for (AnyEntitlement operation : AnyEntitlement.values()) {
+            this.values.add(getFor(anyType, operation));
+        }
+    }
+
+    public void removeFor(final String anyType) {
+        for (AnyEntitlement operation : AnyEntitlement.values()) {
+            this.values.remove(getFor(anyType, operation));
+        }
+    }
+
+    public Set<String> getValues() {
+        return Collections.unmodifiableSet(values);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
new file mode 100644
index 0000000..4600f9a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.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.core.provisioning.api;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.to.AnyTO;
+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.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.identityconnectors.framework.common.objects.Attribute;
+
+public interface MappingManager {
+
+    /**
+     * Get connObjectKey internal value.
+     *
+     * @param any any object
+     * @param provision provision information
+     * @return connObjectKey internal value
+     */
+    String getConnObjectKeyValue(Any<?> any, Provision provision);
+
+    /**
+     * Get attribute values for the given {@link MappingItem} and any objects.
+     *
+     * @param provision provision information
+     * @param mappingItem mapping item
+     * @param anys any objects
+     * @return attribute values.
+     */
+    List<PlainAttrValue> getIntValues(Provision provision, MappingItem mappingItem, List<Any<?>> anys);
+
+    /**
+     * Prepare attributes for sending to a connector instance.
+     *
+     * @param any given any object
+     * @param password clear-text password
+     * @param changePwd whether password should be included for propagation attributes or not
+     * @param enable whether any object must be enabled or not
+     * @param provision provision information
+     * @return connObjectLink + prepared attributes
+     */
+    Pair<String, Set<Attribute>> prepareAttrs(
+            Any<?> any, String password, boolean changePwd, Boolean enable, Provision provision);
+
+    /**
+     * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
+     * connector.
+     *
+     * @param <T> any object
+     * @param mappingItem mapping item
+     * @param attr attribute received from connector
+     * @param anyTO any object
+     * @param anyUtils any utils
+     */
+    <T extends AnyTO> void setIntValues(MappingItem mappingItem, Attribute attr, T anyTO, AnyUtils anyUtils);
+
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 1f9b7ef..cf198fe 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.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserPatch> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
new file mode 100644
index 0000000..5c563c9
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
@@ -0,0 +1,83 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.Uid;
+
+class AttributeDeserializer extends JsonDeserializer<Attribute> {
+
+    @Override
+    public Attribute deserialize(final JsonParser jp, final DeserializationContext ctx)
+            throws IOException {
+
+        ObjectNode tree = jp.readValueAsTree();
+
+        String name = tree.get("name").asText();
+
+        List<Object> values = new ArrayList<Object>();
+        for (Iterator<JsonNode> itor = tree.get("value").iterator(); itor.hasNext();) {
+            JsonNode node = itor.next();
+            if (node.isNull()) {
+                values.add(null);
+            } else if (node.isObject()) {
+                values.add(((ObjectNode) node).traverse(jp.getCodec()).readValueAs(GuardedString.class));
+            } else if (node.isBoolean()) {
+                values.add(node.asBoolean());
+            } else if (node.isDouble()) {
+                values.add(node.asDouble());
+            } else if (node.isLong()) {
+                values.add(node.asLong());
+            } else if (node.isInt()) {
+                values.add(node.asInt());
+            } else {
+                String text = node.asText();
+                if (text.startsWith(AttributeSerializer.BYTE_ARRAY_PREFIX)
+                        && text.endsWith(AttributeSerializer.BYTE_ARRAY_SUFFIX)) {
+
+                    values.add(Base64.decode(StringUtils.substringBetween(
+                            text, AttributeSerializer.BYTE_ARRAY_PREFIX, AttributeSerializer.BYTE_ARRAY_SUFFIX)));
+                } else {
+                    values.add(text);
+                }
+            }
+        }
+
+        return Uid.NAME.equals(name)
+                ? new Uid(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
+                : Name.NAME.equals(name)
+                ? new Name(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
+                : AttributeBuilder.build(name, values);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
new file mode 100644
index 0000000..f8b0fbf
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
@@ -0,0 +1,73 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+
+class AttributeSerializer extends JsonSerializer<Attribute> {
+
+    public static final String BYTE_ARRAY_PREFIX = "<binary>";
+
+    public static final String BYTE_ARRAY_SUFFIX = "</binary>";
+
+    @Override
+    public void serialize(final Attribute source, final JsonGenerator jgen, final SerializerProvider sp)
+            throws IOException {
+
+        jgen.writeStartObject();
+
+        jgen.writeStringField("name", source.getName());
+
+        jgen.writeFieldName("value");
+        if (source.getValue() == null) {
+            jgen.writeNull();
+        } else {
+            jgen.writeStartArray();
+            for (Object value : source.getValue()) {
+                if (value == null) {
+                    jgen.writeNull();
+                } else if (value instanceof GuardedString) {
+                    jgen.writeObject(value);
+                } else if (value instanceof Integer) {
+                    jgen.writeNumber((Integer) value);
+                } else if (value instanceof Long) {
+                    jgen.writeNumber((Long) value);
+                } else if (value instanceof Double) {
+                    jgen.writeNumber((Double) value);
+                } else if (value instanceof Boolean) {
+                    jgen.writeBoolean((Boolean) value);
+                } else if (value instanceof byte[]) {
+                    jgen.writeString(BYTE_ARRAY_PREFIX + Base64.encode((byte[]) value) + BYTE_ARRAY_SUFFIX);
+                } else {
+                    jgen.writeString(value.toString());
+                }
+            }
+            jgen.writeEndArray();
+        }
+
+        jgen.writeEndObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
new file mode 100644
index 0000000..a75319e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
@@ -0,0 +1,93 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.EncryptorFactory;
+import org.identityconnectors.common.security.GuardedString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class GuardedStringDeserializer extends JsonDeserializer<GuardedString> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GuardedStringDeserializer.class);
+
+    @Override
+    public GuardedString deserialize(final JsonParser jp, final DeserializationContext ctx)
+            throws IOException {
+
+        ObjectNode tree = jp.readValueAsTree();
+
+        boolean readOnly = false;
+        if (tree.has("readOnly")) {
+            readOnly = tree.get("readOnly").asBoolean();
+        }
+        boolean disposed = false;
+        if (tree.has("disposed")) {
+            disposed = tree.get("disposed").asBoolean();
+        }
+        byte[] encryptedBytes = null;
+        if (tree.has("encryptedBytes")) {
+            encryptedBytes = Base64.decode(tree.get("encryptedBytes").asText());
+        }
+        String base64SHA1Hash = null;
+        if (tree.has("base64SHA1Hash")) {
+            base64SHA1Hash = tree.get("base64SHA1Hash").asText();
+        }
+
+        final byte[] clearBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(encryptedBytes);
+
+        GuardedString dest = new GuardedString(new String(clearBytes).toCharArray());
+
+        try {
+            Field field = GuardedString.class.getDeclaredField("readOnly");
+            field.setAccessible(true);
+            field.setBoolean(dest, readOnly);
+        } catch (Exception e) {
+            LOG.error("Could not set field value to {}", readOnly, e);
+        }
+
+        try {
+            Field field = GuardedString.class.getDeclaredField("disposed");
+            field.setAccessible(true);
+            field.setBoolean(dest, disposed);
+        } catch (Exception e) {
+            LOG.error("Could not set field value to {}", disposed, e);
+        }
+
+        if (base64SHA1Hash != null) {
+            try {
+                Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
+                field.setAccessible(true);
+                field.set(dest, base64SHA1Hash);
+            } catch (Exception e) {
+                LOG.error("Could not set field value to {}", base64SHA1Hash, e);
+            }
+        }
+
+        return dest;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java
new file mode 100644
index 0000000..49cc87d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java
@@ -0,0 +1,89 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.EncryptorFactory;
+import org.identityconnectors.common.security.GuardedString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class GuardedStringSerializer extends JsonSerializer<GuardedString> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GuardedStringSerializer.class);
+
+    @Override
+    public void serialize(final GuardedString source, final JsonGenerator jgen, final SerializerProvider sp)
+            throws IOException {
+
+        jgen.writeStartObject();
+
+        boolean readOnly = false;
+        try {
+            Field field = GuardedString.class.getDeclaredField("readOnly");
+            field.setAccessible(true);
+            readOnly = field.getBoolean(source);
+        } catch (Exception e) {
+            LOG.error("Could not get field value", e);
+        }
+        jgen.writeBooleanField("readOnly", readOnly);
+
+        boolean disposed = false;
+        try {
+            Field field = GuardedString.class.getDeclaredField("disposed");
+            field.setAccessible(true);
+            disposed = field.getBoolean(source);
+        } catch (Exception e) {
+            LOG.error("Could not get field value", e);
+        }
+        jgen.writeBooleanField("disposed", disposed);
+
+        final StringBuilder cleartext = new StringBuilder();
+        source.access(new GuardedString.Accessor() {
+
+            @Override
+            public void access(final char[] clearChars) {
+                cleartext.append(clearChars);
+            }
+        });
+        byte[] encryptedBytes =
+                EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(cleartext.toString().getBytes());
+        jgen.writeStringField("encryptedBytes", Base64.encode(encryptedBytes));
+
+        String base64SHA1Hash = null;
+        try {
+            Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
+            field.setAccessible(true);
+            base64SHA1Hash = field.get(source).toString();
+        } catch (Exception e) {
+            LOG.error("Could not get field value", e);
+        }
+        if (base64SHA1Hash != null) {
+            jgen.writeStringField("base64SHA1Hash", base64SHA1Hash);
+        }
+
+        jgen.writeEndObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
new file mode 100644
index 0000000..25e4316
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
@@ -0,0 +1,80 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for serialization and deserialization of configuration objects (POJOs) in JSON.
+ */
+public final class POJOHelper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(POJOHelper.class);
+
+    private static final ObjectMapper MAPPER;
+
+    static {
+        SimpleModule pojoModule = new SimpleModule("POJOModule", new Version(1, 0, 0, null, null, null));
+        pojoModule.addSerializer(GuardedString.class, new GuardedStringSerializer());
+        pojoModule.addSerializer(Attribute.class, new AttributeSerializer());
+        pojoModule.addSerializer(SyncToken.class, new SyncTokenSerializer());
+        pojoModule.addDeserializer(GuardedString.class, new GuardedStringDeserializer());
+        pojoModule.addDeserializer(Attribute.class, new AttributeDeserializer());
+        pojoModule.addDeserializer(SyncToken.class, new SyncTokenDeserializer());
+
+        MAPPER = new ObjectMapper();
+        MAPPER.registerModule(pojoModule);
+        MAPPER.registerModule(new AfterburnerModule());
+    }
+
+    public static String serialize(final Object object) {
+        String result = null;
+
+        try {
+            result = MAPPER.writeValueAsString(object);
+        } catch (Exception e) {
+            LOG.error("During serialization", e);
+        }
+
+        return result;
+    }
+
+    public static <T extends Object> T deserialize(final String serialized, final Class<T> reference) {
+        T result = null;
+
+        try {
+            result = MAPPER.readValue(serialized, reference);
+        } catch (Exception e) {
+            LOG.error("During deserialization", e);
+        }
+
+        return result;
+    }
+
+    private POJOHelper() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
new file mode 100644
index 0000000..3f8dc4d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+class SyncTokenDeserializer extends JsonDeserializer<SyncToken> {
+
+    @Override
+    public SyncToken deserialize(final JsonParser jp, final DeserializationContext ctx)
+            throws IOException {
+
+        ObjectNode tree = jp.readValueAsTree();
+
+        Object value = null;
+        if (tree.has("value")) {
+            JsonNode node = tree.get("value");
+            value = node.isNull()
+                    ? null
+                    : node.isBoolean()
+                            ? node.asBoolean()
+                            : node.isDouble()
+                                    ? node.asDouble()
+                                    : node.isLong()
+                                            ? node.asLong()
+                                            : node.isInt()
+                                                    ? node.asInt()
+                                                    : node.asText();
+
+            if (value instanceof String) {
+                String base64 = (String) value;
+                try {
+                    value = Base64.decode(base64);
+                } catch (RuntimeException e) {
+                    value = base64;
+                }
+            }
+        }
+
+        return new SyncToken(value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
new file mode 100644
index 0000000..f9d2ee5
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+class SyncTokenSerializer extends JsonSerializer<SyncToken> {
+
+    @Override
+    public void serialize(final SyncToken source, final JsonGenerator jgen, final SerializerProvider sp)
+            throws IOException {
+
+        jgen.writeStartObject();
+
+        jgen.writeFieldName("value");
+
+        if (source.getValue() == null) {
+            jgen.writeNull();
+        } else if (source.getValue() instanceof Boolean) {
+            jgen.writeBoolean((Boolean) source.getValue());
+        } else if (source.getValue() instanceof Double) {
+            jgen.writeNumber((Double) source.getValue());
+        } else if (source.getValue() instanceof Long) {
+            jgen.writeNumber((Long) source.getValue());
+        } else if (source.getValue() instanceof Integer) {
+            jgen.writeNumber((Integer) source.getValue());
+        } else if (source.getValue() instanceof byte[]) {
+            jgen.writeString(Base64.encode((byte[]) source.getValue()));
+        } else {
+            jgen.writeString(source.getValue().toString());
+        }
+
+        jgen.writeEndObject();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java
deleted file mode 100644
index 6691db3..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java
deleted file mode 100644
index e0ad1d8..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-public interface AnyObjectSyncResultHandler extends SyncopeSyncResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java
deleted file mode 100644
index d22d4e7..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-public interface GroupPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java
deleted file mode 100644
index 907c29c..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-import java.util.Map;
-
-public interface GroupSyncResultHandler extends SyncopeSyncResultHandler {
-
-    Map<Long, String> getGroupOwnerMap();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
deleted file mode 100644
index 8bc9da5..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-/**
- * 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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java
deleted file mode 100644
index 02e6979..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java
deleted file mode 100644
index 2e6e055..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java
deleted file mode 100644
index 9e3c28a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
deleted file mode 100644
index c6d75ae..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/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
deleted file mode 100644
index 874215b..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
deleted file mode 100644
index 2440a1a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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;
-}


[11/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java
deleted file mode 100644
index 52dfdb4..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
deleted file mode 100644
index e77af9a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java
deleted file mode 100644
index 86e7cf0..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java
deleted file mode 100644
index 9eb8dc0..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-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/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java
deleted file mode 100644
index 6f0a3fc..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-public interface UserPushResultHandler extends SyncopePushResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java
deleted file mode 100644
index 9db1269..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/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.sync;
-
-public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..4198b53
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.syncpull;
+
+public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..dba6377
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.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.syncpull;
+
+public interface AnyObjectSyncResultHandler extends SyncopeSyncResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..457c78e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.syncpull;
+
+public interface GroupPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..19c8b8f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.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.syncpull;
+
+import java.util.Map;
+
+public interface GroupSyncResultHandler extends SyncopeSyncResultHandler {
+
+    Map<Long, String> getGroupOwnerMap();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..cdd885a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..7479c96
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..08ab034
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..1e82796d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..75e5a5f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..cc073ce
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..ae072b7
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.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.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/28569df5/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
new file mode 100644
index 0000000..dff841a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.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.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/28569df5/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
new file mode 100644
index 0000000..deb6e9b
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..c078ef2
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..5c293830
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.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.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/28569df5/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
new file mode 100644
index 0000000..8a0459a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.syncpull;
+
+public interface UserPushResultHandler extends SyncopePushResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..7f9c827
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.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.syncpull;
+
+public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java
new file mode 100644
index 0000000..07f929a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java
@@ -0,0 +1,69 @@
+/*
+ * 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.utils;
+
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
+import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
+
+public final class ConnPoolConfUtils {
+
+    public static ConnPoolConf getConnPoolConf(final ConnPoolConfTO cpcto, final ConnPoolConf cpc) {
+        ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
+
+        cpc.setMaxIdle(cpcto.getMaxIdle() == null ? opc.getMaxIdle() : cpcto.getMaxIdle());
+        cpc.setMaxObjects(cpcto.getMaxObjects() == null ? opc.getMaxObjects() : cpcto.getMaxObjects());
+        cpc.setMaxWait(cpcto.getMaxWait() == null ? opc.getMaxWait() : cpcto.getMaxWait());
+        cpc.setMinEvictableIdleTimeMillis(cpcto.getMinEvictableIdleTimeMillis() == null
+                ? opc.getMinEvictableIdleTimeMillis() : cpcto.getMinEvictableIdleTimeMillis());
+        cpc.setMinIdle(cpcto.getMinIdle() == null ? opc.getMinIdle() : cpcto.getMinIdle());
+
+        return cpc;
+    }
+
+    public static ObjectPoolConfiguration getObjectPoolConfiguration(final ConnPoolConf cpc) {
+        ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
+        updateObjectPoolConfiguration(opc, cpc);
+        return opc;
+    }
+
+    public static void updateObjectPoolConfiguration(
+            final ObjectPoolConfiguration opc, final ConnPoolConf cpc) {
+
+        if (cpc.getMaxIdle() != null) {
+            opc.setMaxIdle(cpc.getMaxIdle());
+        }
+        if (cpc.getMaxObjects() != null) {
+            opc.setMaxObjects(cpc.getMaxObjects());
+        }
+        if (cpc.getMaxWait() != null) {
+            opc.setMaxWait(cpc.getMaxWait());
+        }
+        if (cpc.getMinEvictableIdleTimeMillis() != null) {
+            opc.setMinEvictableIdleTimeMillis(cpc.getMinEvictableIdleTimeMillis());
+        }
+        if (cpc.getMinIdle() != null) {
+            opc.setMinIdle(cpc.getMinIdle());
+        }
+    }
+
+    private ConnPoolConfUtils() {
+        // empty constructor for static utility class
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java
new file mode 100644
index 0000000..a744372
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java
@@ -0,0 +1,41 @@
+/*
+ * 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.utils;
+
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public final class EntityUtils {
+
+    public static <KEY, E extends Entity<KEY>> Transformer<E, KEY> keyTransformer() {
+        return new Transformer<E, KEY>() {
+
+            @Override
+            public KEY transform(final E input) {
+                return input.getKey();
+            }
+        };
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private EntityUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
new file mode 100644
index 0000000..4045207
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
@@ -0,0 +1,47 @@
+/*
+ * 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.utils;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
+public final class ExceptionUtils2 {
+
+    /**
+     * Uses commons lang's ExceptionUtils to provide a representation of the full stack trace of the given throwable.
+     *
+     * @param t throwable to build stack trace from
+     * @return a string representation of full stack trace of the given throwable
+     */
+    public static String getFullStackTrace(final Throwable t) {
+        StringBuilder result = new StringBuilder();
+
+        for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
+            result.append(ExceptionUtils.getMessage(throwable)).append('\n').
+                    append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private ExceptionUtils2() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java
new file mode 100644
index 0000000..e1c7ce5
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.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.api.utils;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+
+/**
+ * Utility class for parsing / formatting date and numbers.
+ */
+public final class FormatUtils {
+
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+        @Override
+        protected SimpleDateFormat initialValue() {
+            SimpleDateFormat sdf = new SimpleDateFormat();
+            sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+            return sdf;
+        }
+    };
+
+    private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
+
+        @Override
+        protected DecimalFormat initialValue() {
+            DecimalFormat df = new DecimalFormat();
+            df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+            return df;
+        }
+    };
+
+    public static String format(final Date date) {
+        return format(date, true);
+    }
+
+    public static String format(final Date date, final boolean lenient) {
+        return format(date, lenient, null);
+    }
+
+    public static String format(final Date date, final boolean lenient, final String conversionPattern) {
+        SimpleDateFormat sdf = DATE_FORMAT.get();
+        if (conversionPattern != null) {
+            sdf.applyPattern(conversionPattern);
+        }
+        sdf.setLenient(lenient);
+        return sdf.format(date);
+    }
+
+    public static String format(final long number) {
+        return format(number, null);
+    }
+
+    public static String format(final long number, final String conversionPattern) {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        if (conversionPattern != null) {
+            df.applyPattern(conversionPattern);
+        }
+        return df.format(number);
+    }
+
+    public static String format(final double number) {
+        return format(number, null);
+    }
+
+    public static String format(final double number, final String conversionPattern) {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        if (conversionPattern != null) {
+            df.applyPattern(conversionPattern);
+        }
+        return df.format(number);
+    }
+
+    public static Date parseDate(final String source) throws ParseException {
+        return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
+    }
+
+    public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
+        SimpleDateFormat sdf = DATE_FORMAT.get();
+        sdf.applyPattern(conversionPattern);
+        sdf.setLenient(false);
+        return sdf.parse(source);
+    }
+
+    public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        df.applyPattern(conversionPattern);
+        return df.parse(source);
+    }
+
+    public static void clear() {
+        DATE_FORMAT.remove();
+        DECIMAL_FORMAT.remove();
+    }
+
+    private FormatUtils() {
+        // private empty constructor
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
new file mode 100644
index 0000000..47703b0
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.utils;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class RealmUtils {
+
+    public static String getGroupOwnerRealm(final String realmPath, final Long groupKey) {
+        return realmPath + "@" + groupKey;
+    }
+
+    public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {
+        boolean dontAdd = false;
+        Set<String> toRemove = new HashSet<>();
+        for (String realm : realms) {
+            if (newRealm.startsWith(realm)) {
+                dontAdd = true;
+            } else if (realm.startsWith(newRealm)) {
+                toRemove.add(realm);
+            }
+        }
+
+        realms.removeAll(toRemove);
+        if (!dontAdd) {
+            realms.add(newRealm);
+        }
+        return !dontAdd;
+    }
+
+    public static Set<String> normalize(final Collection<String> realms) {
+        Set<String> normalized = new HashSet<>();
+        if (realms != null) {
+            for (String realm : realms) {
+                normalizingAddTo(normalized, realm);
+            }
+        }
+
+        return normalized;
+    }
+
+    private RealmUtils() {
+        // empty constructor for static utility class 
+    }
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
new file mode 100644
index 0000000..22be516
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.utils.policy;
+
+public class AccountPolicyException extends PolicyException {
+
+    private static final long serialVersionUID = 2779416455067691813L;
+
+    public AccountPolicyException() {
+        super();
+    }
+
+    public AccountPolicyException(final String message) {
+        super(message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
new file mode 100644
index 0000000..9b79189
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
@@ -0,0 +1,37 @@
+/*
+ * 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.utils.policy;
+
+/**
+ * Raise when the merge of two or more PasswordRuleconf instances led to an inconsistent condition.
+ *
+ * @see org.apache.syncope.common.lib.policy.PasswordRuleConf
+ */
+public class InvalidPasswordRuleConf extends Exception {
+
+    private static final long serialVersionUID = 4810651743226663580L;
+
+    public InvalidPasswordRuleConf(final String msg) {
+        super(msg);
+    }
+
+    public InvalidPasswordRuleConf(final String msg, final Exception e) {
+        super(msg, e);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
new file mode 100644
index 0000000..2a49a20
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.utils.policy;
+
+public class PasswordPolicyException extends PolicyException {
+
+    private static final long serialVersionUID = 8072104484395278469L;
+
+    public PasswordPolicyException() {
+        super();
+    }
+
+    public PasswordPolicyException(final String message) {
+        super(message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
new file mode 100644
index 0000000..f11d202
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.utils.policy;
+
+public class PolicyException extends RuntimeException {
+
+    private static final long serialVersionUID = -6082115004491662910L;
+
+    public PolicyException() {
+        super();
+    }
+
+    public PolicyException(final String message) {
+        super(message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
new file mode 100644
index 0000000..a853f0e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
@@ -0,0 +1,50 @@
+/*
+ * 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.utils.policy;
+
+import java.util.regex.Pattern;
+
+public final class PolicyPattern {
+
+    public static final Pattern DIGIT = Pattern.compile(".*\\d+.*");
+
+    public static final Pattern ALPHA_LOWERCASE = Pattern.compile(".*[a-z]+.*");
+
+    public static final Pattern ALPHA_UPPERCASE = Pattern.compile(".*[A-Z]+.*");
+
+    public static final Pattern FIRST_DIGIT = Pattern.compile("\\d.*");
+
+    public static final Pattern LAST_DIGIT = Pattern.compile(".*\\d");
+
+    public static final Pattern ALPHANUMERIC = Pattern.compile(".*\\w.*");
+
+    public static final Pattern FIRST_ALPHANUMERIC = Pattern.compile("\\w.*");
+
+    public static final Pattern LAST_ALPHANUMERIC = Pattern.compile(".*\\w");
+
+    public static final Pattern NON_ALPHANUMERIC = Pattern.compile(".*\\W.*");
+
+    public static final Pattern FIRST_NON_ALPHANUMERIC = Pattern.compile("\\W.*");
+
+    public static final Pattern LAST_NON_ALPHANUMERIC = Pattern.compile(".*\\W");
+
+    private PolicyPattern() {
+        // private constructor for static utility class
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index ee6bfc6..7956dad 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -45,6 +45,11 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-jexl3</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context-support</artifactId>
     </dependency>
@@ -61,7 +66,7 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-misc</artifactId>
+      <artifactId>syncope-core-spring</artifactId>
       <version>${project.version}</version>
     </dependency>
     


[06/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..bd13365
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..258e106
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..42762f2
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.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.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/28569df5/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
new file mode 100644
index 0000000..bf2cd6e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..6f83727
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..a8c6c1b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.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.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;
+    }
+}


[13/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
new file mode 100644
index 0000000..ba9255a
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.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.core.persistence.api.search;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+/**
+ * Converts FIQL expressions to Syncope's {@link SearchCond}.
+ */
+public final class SearchCondConverter {
+
+    /**
+     * Parses a FIQL expression into Syncope's <tt>SearchCond</tt>, using CXF's <tt>FiqlParser</tt>.
+     *
+     * @param fiqlExpression FIQL string
+     * @param realms optional realm to provide to {@link SearchCondVisitor}
+     * @return {@link SearchCond} instance for given FIQL expression
+     * @see FiqlParser
+     */
+    public static SearchCond convert(final String fiqlExpression, final String... realms) {
+        FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
+                SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
+
+        try {
+            SearchCondVisitor searchCondVisitor = new SearchCondVisitor();
+            if (realms != null && realms.length > 0) {
+                searchCondVisitor.setRealm(realms[0]);
+            }
+            searchCondVisitor.visit(fiqlParser.parse(fiqlExpression));
+            return searchCondVisitor.getQuery();
+        } catch (Exception e) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
+            sce.getElements().add(fiqlExpression);
+            sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
+            throw sce;
+        }
+    }
+
+    private SearchCondConverter() {
+        // empty constructor for static utility class        
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
new file mode 100644
index 0000000..79fe904
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
@@ -0,0 +1,222 @@
+/*
+ * 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.search;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.cxf.jaxrs.ext.search.ConditionType;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.SearchUtils;
+import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
+import org.apache.syncope.common.lib.EntityTOUtils;
+import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
+
+/**
+ * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
+ */
+public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean, SearchCond> {
+
+    private String realm;
+
+    private SearchCond searchCond;
+
+    public SearchCondVisitor() {
+        super(null);
+    }
+
+    public void setRealm(final String realm) {
+        this.realm = realm;
+    }
+
+    private AttributeCond createAttributeCond(final String schema) {
+        AttributeCond attributeCond = EntityTOUtils.ANY_FIELDS.contains(schema)
+                ? new AnyCond()
+                : new AttributeCond();
+        attributeCond.setSchema(schema);
+        return attributeCond;
+    }
+
+    private SearchCond visitPrimitive(final SearchCondition<SearchBean> sc) {
+        String name = getRealPropertyName(sc.getStatement().getProperty());
+        SpecialAttr specialAttrName = SpecialAttr.fromString(name);
+
+        String value = SearchUtils.toSqlWildcardString(sc.getStatement().getValue().toString(), false).
+                replaceAll("\\\\_", "_");
+        SpecialAttr specialAttrValue = SpecialAttr.fromString(value);
+
+        AttributeCond attributeCond = createAttributeCond(name);
+        attributeCond.setExpression(value);
+
+        SearchCond leaf;
+        switch (sc.getConditionType()) {
+            case EQUALS:
+            case NOT_EQUALS:
+                if (specialAttrName == null) {
+                    if (specialAttrValue != null && specialAttrValue == SpecialAttr.NULL) {
+                        attributeCond.setType(AttributeCond.Type.ISNULL);
+                        attributeCond.setExpression(null);
+                    } else if (value.indexOf('%') == -1) {
+                        attributeCond.setType(AttributeCond.Type.EQ);
+                    } else {
+                        attributeCond.setType(AttributeCond.Type.LIKE);
+                    }
+
+                    leaf = SearchCond.getLeafCond(attributeCond);
+                } else {
+                    switch (specialAttrName) {
+                        case TYPE:
+                            AnyTypeCond typeCond = new AnyTypeCond();
+                            typeCond.setAnyTypeName(value);
+                            leaf = SearchCond.getLeafCond(typeCond);
+                            break;
+
+                        case RESOURCES:
+                            ResourceCond resourceCond = new ResourceCond();
+                            resourceCond.setResourceName(value);
+                            leaf = SearchCond.getLeafCond(resourceCond);
+                            break;
+
+                        case GROUPS:
+                            MembershipCond groupCond = new MembershipCond();
+                            groupCond.setGroupKey(Long.valueOf(value));
+                            leaf = SearchCond.getLeafCond(groupCond);
+                            break;
+
+                        case RELATIONSHIPS:
+                            RelationshipCond relationshipCond = new RelationshipCond();
+                            relationshipCond.setAnyObjectKey(Long.valueOf(value));
+                            leaf = SearchCond.getLeafCond(relationshipCond);
+                            break;
+
+                        case RELATIONSHIP_TYPES:
+                            RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+                            relationshipTypeCond.setRelationshipTypeKey(value);
+                            leaf = SearchCond.getLeafCond(relationshipTypeCond);
+                            break;
+
+                        case ROLES:
+                            RoleCond roleCond = new RoleCond();
+                            roleCond.setRoleKey(value);
+                            leaf = SearchCond.getLeafCond(roleCond);
+                            break;
+
+                        case ASSIGNABLE:
+                            AssignableCond assignableCond = new AssignableCond();
+                            assignableCond.setRealmFullPath(realm);
+                            leaf = SearchCond.getLeafCond(assignableCond);
+                            break;
+
+                        default:
+                            throw new IllegalArgumentException(
+                                    String.format("Special attr name %s is not supported", specialAttrName));
+                    }
+                }
+                if (sc.getConditionType() == ConditionType.NOT_EQUALS) {
+                    if (leaf.getAttributeCond() != null
+                            && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
+
+                        leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
+                    } else if (leaf.getAnyCond() != null
+                            && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
+
+                        leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
+                    } else {
+                        leaf = SearchCond.getNotLeafCond(leaf);
+                    }
+                }
+                break;
+
+            case GREATER_OR_EQUALS:
+                attributeCond.setType(AttributeCond.Type.GE);
+                leaf = SearchCond.getLeafCond(attributeCond);
+                break;
+
+            case GREATER_THAN:
+                attributeCond.setType(AttributeCond.Type.GT);
+                leaf = SearchCond.getLeafCond(attributeCond);
+                break;
+
+            case LESS_OR_EQUALS:
+                attributeCond.setType(AttributeCond.Type.LE);
+                leaf = SearchCond.getLeafCond(attributeCond);
+                break;
+
+            case LESS_THAN:
+                attributeCond.setType(AttributeCond.Type.LT);
+                leaf = SearchCond.getLeafCond(attributeCond);
+                break;
+
+            default:
+                throw new IllegalArgumentException(
+                        String.format("Condition type %s is not supported", sc.getConditionType().name()));
+        }
+
+        return leaf;
+    }
+
+    private SearchCond visitCompount(final SearchCondition<SearchBean> sc) {
+        List<SearchCond> searchConds = new ArrayList<>();
+        for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
+            searchConds.add(searchCondition.getStatement() == null
+                    ? visitCompount(searchCondition)
+                    : visitPrimitive(searchCondition));
+        }
+
+        SearchCond compound;
+        switch (sc.getConditionType()) {
+            case AND:
+                compound = SearchCond.getAndCond(searchConds);
+                break;
+
+            case OR:
+                compound = SearchCond.getOrCond(searchConds);
+                break;
+
+            default:
+                throw new IllegalArgumentException(
+                        String.format("Condition type %s is not supported", sc.getConditionType().name()));
+        }
+
+        return compound;
+    }
+
+    @Override
+    public void visit(final SearchCondition<SearchBean> sc) {
+        searchCond = sc.getStatement() == null
+                ? visitCompount(sc)
+                : visitPrimitive(sc);
+    }
+
+    @Override
+    public SearchCond getQuery() {
+        return searchCond;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
new file mode 100644
index 0000000..05a8cdc
--- /dev/null
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.search;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
+import org.junit.Test;
+
+public class SearchCondConverterTest {
+
+    @Test
+    public void eq() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
+        assertEquals("username==rossini", fiqlExpression);
+
+        AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
+        attrCond.setSchema("username");
+        attrCond.setExpression("rossini");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void like() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
+        assertEquals("username==ros*", fiqlExpression);
+
+        AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
+        attrCond.setSchema("username");
+        attrCond.setExpression("ros%");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void isNull() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
+        assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
+
+        AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
+        attrCond.setSchema("loginDate");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void isNotNull() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
+        assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
+
+        AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
+        attrCond.setSchema("loginDate");
+        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void relationships() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationships(1L).query();
+        assertEquals(SpecialAttr.RELATIONSHIPS + "==1", fiqlExpression);
+
+        RelationshipCond relationshipCond = new RelationshipCond();
+        relationshipCond.setAnyObjectKey(1L);
+        SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void relationshipTypes() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
+        assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
+
+        RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
+        relationshipCond.setRelationshipTypeKey("type1");
+        SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+
+        fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
+        assertEquals(
+                SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
+                fiqlExpression);
+    }
+
+    @Test
+    public void groups() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
+        assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
+
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroupKey(1L);
+        SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void roles() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
+        assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
+
+        RoleCond roleCond = new RoleCond();
+        roleCond.setRoleKey("User reviewer");
+        SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void resources() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
+        assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
+
+        ResourceCond resCond = new ResourceCond();
+        resCond.setResourceName("resource-ldap");
+        SearchCond simpleCond = SearchCond.getLeafCond(resCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void assignable() {
+        String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
+        assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
+
+        AssignableCond assignableCond = new AssignableCond();
+        assignableCond.setRealmFullPath("/even/two");
+        SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
+    }
+
+    @Test
+    public void type() {
+        String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
+        assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+
+        AnyTypeCond acond = new AnyTypeCond();
+        acond.setAnyTypeName("PRINTER");
+        SearchCond simpleCond = SearchCond.getLeafCond(acond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void and() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().
+                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
+        assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
+
+        AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond1.setSchema("fullname");
+        fullnameLeafCond1.setExpression("%o%");
+        AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond2.setSchema("fullname");
+        fullnameLeafCond2.setExpression("%i%");
+        SearchCond andCond = SearchCond.getAndCond(
+                SearchCond.getLeafCond(fullnameLeafCond1),
+                SearchCond.getLeafCond(fullnameLeafCond2));
+
+        assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
+    public void or() {
+        String fiqlExpression = new UserFiqlSearchConditionBuilder().
+                is("fullname").equalTo("*o*", "*i*", "*ini").query();
+        assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+        fiqlExpression = new UserFiqlSearchConditionBuilder().
+                is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
+        assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+
+        AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond1.setSchema("fullname");
+        fullnameLeafCond1.setExpression("%o%");
+        AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond2.setSchema("fullname");
+        fullnameLeafCond2.setExpression("%i%");
+        AttributeCond fullnameLeafCond3 = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond3.setSchema("fullname");
+        fullnameLeafCond3.setExpression("%ini");
+        SearchCond orCond = SearchCond.getOrCond(
+                SearchCond.getLeafCond(fullnameLeafCond1),
+                SearchCond.getOrCond(
+                        SearchCond.getLeafCond(fullnameLeafCond2),
+                        SearchCond.getLeafCond(fullnameLeafCond3)));
+
+        assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index ee900a5..9126d55 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -83,16 +83,16 @@ under the License.
       <groupId>org.aspectj</groupId>
       <artifactId>aspectjweaver</artifactId>
     </dependency>
-    
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
+
     <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
     </dependency>
-            
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-jexl3</artifactId>
+    </dependency>
+      
     <dependency>
       <groupId>org.quartz-scheduler</groupId>
       <artifactId>quartz</artifactId>
@@ -105,7 +105,7 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-misc</artifactId>
+      <artifactId>syncope-core-spring</artifactId>
       <version>${project.version}</version>
     </dependency>
         

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
index 9cf2b32..e37eb50 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
@@ -27,7 +27,7 @@ import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Hex;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.DataAccessException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index c70c7c7..0e7d059 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -50,8 +50,8 @@ import javax.xml.transform.stream.StreamResult;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 5d8cfc5..c4c7d90 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -27,8 +27,8 @@ import javax.sql.DataSource;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
 import org.springframework.core.io.support.PropertiesLoaderUtils;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index 3dbf25d..acbde6e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import javax.persistence.EntityManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.DAO;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
index f2156fc..256ffe6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
@@ -23,7 +23,7 @@ import java.util.regex.Pattern;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
 import org.apache.syncope.core.persistence.api.dao.AccountRule;
 import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
index 1ce560a..39a02c0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
@@ -22,8 +22,8 @@ import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
 import org.apache.syncope.core.persistence.api.dao.PasswordRule;
 import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 4513837..f758ad9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -35,10 +35,10 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.AnyEntitlement;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index b0b1162..88c6cbf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -39,8 +39,8 @@ 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.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index ece8d6c..9a6fe41 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -38,10 +38,10 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 406a378..e8b4816 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -22,7 +22,7 @@ import java.util.List;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 822c02d..62d179f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -41,11 +41,11 @@ import org.apache.syncope.common.lib.policy.PasswordRuleConf;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.dao.AccountRule;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
index e6ead6f..ad38542 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -27,7 +27,7 @@ import javax.persistence.MappedSuperclass;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.Realm;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
index 754da9f..21f835b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
@@ -32,13 +32,13 @@ 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.AttrSchemaType;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrValueCheck;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
 
 @MappedSuperclass
 @PlainAttrValueCheck

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
index c63a401..23a3815 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
@@ -22,7 +22,7 @@ import java.util.Date;
 import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
index 6aaf62d..1fa004b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index d59982e..f018670 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -44,7 +44,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @Entity

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
index 3e9169e..f9bb394 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
@@ -24,7 +24,7 @@ import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.persistence.api.entity.Domain;
 import org.apache.syncope.core.persistence.jpa.validation.entity.DomainCheck;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
index df08af8..d744976 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
@@ -25,7 +25,7 @@ import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 
 @Entity
 @Table(name = JPAReportletConfInstance.TABLE)

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index 7444bd3..e1fcbdd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -37,7 +37,7 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
index c5099f3..146b127 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
@@ -37,7 +37,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
index 782e6b4..d19c06e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
@@ -24,7 +24,7 @@ import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
index 4b39dc8..dcc543a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
@@ -24,7 +24,7 @@ import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
index 3bc0009..7b0c1ef 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
@@ -23,7 +23,7 @@ import javax.persistence.Lob;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.policy.PushPolicySpec;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
 
 @Entity

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
index 913ee54..9d2a518 100644
--- 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
@@ -23,7 +23,7 @@ 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.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
 
 @Entity

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
index 28febea..ed6f581 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
@@ -22,7 +22,7 @@ import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 12d5959..5900f68 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
@@ -52,7 +52,7 @@ 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.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
index 3906dfd..ec50d2c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
@@ -28,7 +28,7 @@ import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import javax.validation.constraints.NotNull;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
index 94c7d8d..1be6b9b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -35,7 +35,7 @@ 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.jpa.validation.entity.PropagationTaskCheck;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.identityconnectors.framework.common.objects.Attribute;
 
 /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index c8e6672..d8a1908 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -57,9 +57,9 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.security.SecureRandomUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
new file mode 100644
index 0000000..691f5e4
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.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.persistence.jpa.spring;
+
+import java.lang.reflect.Method;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
+ * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
+ * {@link AuthContextUtils#getDomain()}.
+ */
+public class DomainTransactionInterceptor extends TransactionInterceptor {
+
+    private static final long serialVersionUID = 5113728988680448551L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
+
+    @Override
+    public TransactionAttributeSource getTransactionAttributeSource() {
+        final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
+
+        return new TransactionAttributeSource() {
+
+            @Override
+            public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
+                TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
+
+                if (txAttr instanceof DefaultTransactionAttribute) {
+                    ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
+                }
+
+                return txAttr;
+            }
+        };
+    }
+
+    @Override
+    public Object invoke(final MethodInvocation invocation) throws Throwable {
+        try {
+            return super.invoke(invocation);
+        } catch (Throwable e) {
+            LOG.debug("Error during {} invocation", invocation.getMethod(), e);
+            throw e;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
new file mode 100644
index 0000000..0353497
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.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.persistence.jpa.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Replaces Spring's {@link TransactionInterceptor} with {@link DomainTransactionInterceptor}.
+ */
+public class DomainTransactionInterceptorInjector implements BeanFactoryPostProcessor {
+
+    @Override
+    public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
+        bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
index 1ce2190..ecb0edb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
@@ -21,8 +21,8 @@ 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.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.provisioning.api.URIUtils;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.URIUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
 
 public class ConnInstanceValidator extends AbstractValidator<ConnInstanceCheck, ConnInstance> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
index 0b60c5e..9d86b88 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -25,7 +25,7 @@ import javax.validation.ConstraintViolation;
 import javax.validation.Validator;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.Entity;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 941e63c..7b145d4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 72b421e..da90bd4 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
@@ -25,9 +25,9 @@ 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;
+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;
 
 public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/domains.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains.xml b/core/persistence-jpa/src/main/resources/domains.xml
index 5d6b5ab..42f87d0 100644
--- a/core/persistence-jpa/src/main/resources/domains.xml
+++ b/core/persistence-jpa/src/main/resources/domains.xml
@@ -24,7 +24,7 @@ under the License.
   
   <import resource="classpath*:domains/*Domain.xml"/>
   
-  <bean class="org.apache.syncope.core.misc.spring.DomainTransactionInterceptorInjector"/>
+  <bean class="org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptorInjector"/>
   
   <bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
     <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
index 5cb38c2..f949e32 100644
--- a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
+++ b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
@@ -28,11 +28,11 @@ under the License.
                            http://www.springframework.org/schema/util
                            http://www.springframework.org/schema/util/spring-util.xsd">
   
-  <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="MasterContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
     <property name="fallback" value="classpath:domains/MasterContent.xml"/>
   </bean>
-  <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="MasterProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/Master.properties"/>
     <property name="fallback" value="classpath:domains/Master.properties"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/persistenceContext.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContext.xml b/core/persistence-jpa/src/main/resources/persistenceContext.xml
index ad2d837..4d12fa1 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContext.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContext.xml
@@ -33,11 +33,11 @@ under the License.
 
   <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
 
-  <bean id="viewsXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="viewsXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/views.xml"/>
     <property name="fallback" value="classpath:views.xml"/>
   </bean>
-  <bean id="indexesXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="indexesXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/indexes.xml"/>
     <property name="fallback" value="classpath:indexes.xml"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index bffe55f..f59ac32 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.persistence.jpa;
 
 import javax.persistence.EntityManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.junit.runner.RunWith;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
index 9366705..4b402bd 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
@@ -30,8 +30,8 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
-import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
index 3cea9ab..b033ecb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
@@ -39,7 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 fc8305b..6762b7f 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
@@ -30,7 +30,7 @@ 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.core.misc.serialization.POJOHelper;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index 44b888b..810534b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -33,8 +33,8 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index 33980a2..7c7df15 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -31,7 +31,7 @@ import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index f9d284f..544a470 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -30,7 +30,7 @@ import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;


[05/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..84504ec
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.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.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/28569df5/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
new file mode 100644
index 0000000..49135f9
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..f82b40c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..159382c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.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.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/28569df5/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
new file mode 100644
index 0000000..0455b08
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..8b73e42
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.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.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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..464c56b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
@@ -0,0 +1,335 @@
+/*
+ * 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/28569df5/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
new file mode 100644
index 0000000..134c1f1
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.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.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/28569df5/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
new file mode 100644
index 0000000..343ba3f
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.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.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/28569df5/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
new file mode 100644
index 0000000..4d44086
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/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.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/28569df5/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
new file mode 100644
index 0000000..78f253a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.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.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/28569df5/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
new file mode 100644
index 0000000..9038b42
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.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.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;
+    }
+}


[15/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
deleted file mode 100644
index 8ab1d31..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
+++ /dev/null
@@ -1,43 +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.misc.security;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.web.access.AccessDeniedHandlerImpl;
-
-/**
- * Render Spring's {@link AccessDeniedException} as other Syncope errors.
- */
-public class SyncopeAccessDeniedHandler extends AccessDeniedHandlerImpl {
-
-    @Override
-    public void handle(final HttpServletRequest request, final HttpServletResponse response,
-            final AccessDeniedException accessDeniedException) throws IOException, ServletException {
-
-        response.addHeader(RESTHeaders.ERROR_INFO, accessDeniedException.getMessage());
-
-        super.handle(request, response, accessDeniedException);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
deleted file mode 100644
index 68b27f4..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
+++ /dev/null
@@ -1,86 +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.misc.security;
-
-import java.io.Serializable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-
-public class SyncopeAuthenticationDetails implements Serializable {
-
-    private static final long serialVersionUID = -5899959397393502897L;
-
-    private final String remoteAddress;
-
-    private final String sessionId;
-
-    private String domain;
-
-    public SyncopeAuthenticationDetails(final HttpServletRequest request) {
-        this.remoteAddress = request.getRemoteAddr();
-
-        HttpSession session = request.getSession(false);
-        this.sessionId = session == null ? null : session.getId();
-
-        this.domain = request.getHeader(RESTHeaders.DOMAIN);
-    }
-
-    public SyncopeAuthenticationDetails(final String domain) {
-        this.remoteAddress = null;
-        this.sessionId = null;
-        this.domain = domain;
-    }
-
-    public String getRemoteAddress() {
-        return remoteAddress;
-    }
-
-    public String getSessionId() {
-        return sessionId;
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-
-    public void setDomain(final String domain) {
-        this.domain = domain;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
-    }
-
-    @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
deleted file mode 100644
index b943edf..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
+++ /dev/null
@@ -1,32 +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.misc.security;
-
-import javax.servlet.http.HttpServletRequest;
-import org.springframework.security.authentication.AuthenticationDetailsSource;
-
-public class SyncopeAuthenticationDetailsSource
-        implements AuthenticationDetailsSource<HttpServletRequest, SyncopeAuthenticationDetails> {
-
-    @Override
-    public SyncopeAuthenticationDetails buildDetails(final HttpServletRequest context) {
-        return new SyncopeAuthenticationDetails(context);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
deleted file mode 100644
index 6213264..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
+++ /dev/null
@@ -1,43 +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.misc.security;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
-
-/**
- * Render Spring's {@link AuthenticationException} as other Syncope errors.
- */
-public class SyncopeAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
-
-    @Override
-    public void commence(final HttpServletRequest request, final HttpServletResponse response,
-            final AuthenticationException authException) throws IOException, ServletException {
-
-        response.addHeader(RESTHeaders.ERROR_INFO, authException.getMessage());
-
-        super.commence(request, response, authException);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
deleted file mode 100644
index 313b0f1..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ /dev/null
@@ -1,210 +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.misc.security;
-
-import javax.annotation.Resource;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.misc.security.AuthContextUtils.Executable;
-import org.apache.syncope.core.persistence.api.entity.Domain;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-@Configurable
-public class SyncopeAuthenticationProvider implements AuthenticationProvider {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
-
-    @Autowired
-    protected AuthDataAccessor dataAccessor;
-
-    @Autowired
-    protected UserProvisioningManager provisioningManager;
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    @Resource(name = "anonymousUser")
-    protected String anonymousUser;
-
-    protected String adminPassword;
-
-    protected String adminPasswordAlgorithm;
-
-    protected String anonymousKey;
-
-    protected UserDetailsService userDetailsService;
-
-    protected final Encryptor encryptor = Encryptor.getInstance();
-
-    /**
-     * @param adminPassword the adminPassword to set
-     */
-    public void setAdminPassword(final String adminPassword) {
-        this.adminPassword = adminPassword;
-    }
-
-    /**
-     * @param adminPasswordAlgorithm the adminPasswordAlgorithm to set
-     */
-    public void setAdminPasswordAlgorithm(final String adminPasswordAlgorithm) {
-        this.adminPasswordAlgorithm = adminPasswordAlgorithm;
-    }
-
-    /**
-     * @param anonymousKey the anonymousKey to set
-     */
-    public void setAnonymousKey(final String anonymousKey) {
-        this.anonymousKey = anonymousKey;
-    }
-
-    public void setUserDetailsService(final UserDetailsService syncopeUserDetailsService) {
-        this.userDetailsService = syncopeUserDetailsService;
-    }
-
-    @Override
-    public Authentication authenticate(final Authentication authentication) {
-        String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
-        if (StringUtils.isBlank(domainKey)) {
-            domainKey = SyncopeConstants.MASTER_DOMAIN;
-        }
-        SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
-
-        Boolean authenticated;
-        if (anonymousUser.equals(authentication.getName())) {
-            authenticated = authentication.getCredentials().toString().equals(anonymousKey);
-        } else if (adminUser.equals(authentication.getName())) {
-            if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
-                authenticated = encryptor.verify(
-                        authentication.getCredentials().toString(),
-                        CipherAlgorithm.valueOf(adminPasswordAlgorithm),
-                        adminPassword);
-            } else {
-                final String domainToFind = domainKey;
-                authenticated = AuthContextUtils.execWithAuthContext(
-                        SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
-
-                            @Override
-                            public Boolean exec() {
-                                Domain domain = dataAccessor.findDomain(domainToFind);
-
-                                return encryptor.verify(
-                                        authentication.getCredentials().toString(),
-                                        domain.getAdminCipherAlgorithm(),
-                                        domain.getAdminPwd());
-                            }
-                        });
-            }
-        } else {
-            final Pair<Long, Boolean> authResult =
-                    AuthContextUtils.execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
-
-                        @Override
-                        public Pair<Long, Boolean> exec() {
-                            return dataAccessor.authenticate(authentication);
-                        }
-                    });
-            authenticated = authResult.getValue();
-            if (authenticated != null && !authenticated) {
-                AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
-
-                    @Override
-                    public Void exec() {
-                        provisioningManager.internalSuspend(authResult.getKey());
-                        return null;
-                    }
-                });
-            }
-        }
-
-        final boolean isAuthenticated = authenticated != null && authenticated;
-        UsernamePasswordAuthenticationToken token;
-        if (isAuthenticated) {
-            token = AuthContextUtils.execWithAuthContext(
-                    domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
-
-                        @Override
-                        public UsernamePasswordAuthenticationToken exec() {
-                            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
-                                    authentication.getPrincipal(),
-                                    null,
-                                    userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
-                                    getAuthorities());
-                            token.setDetails(authentication.getDetails());
-
-                            dataAccessor.audit(
-                                    AuditElements.EventCategoryType.REST,
-                                    AuditElements.AUTHENTICATION_CATEGORY,
-                                    null,
-                                    AuditElements.LOGIN_EVENT,
-                                    Result.SUCCESS,
-                                    null,
-                                    isAuthenticated,
-                                    authentication,
-                                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
-                            return token;
-                        }
-                    });
-
-            LOG.debug("User {} successfully authenticated, with entitlements {}",
-                    authentication.getPrincipal(), token.getAuthorities());
-        } else {
-            AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
-
-                @Override
-                public Void exec() {
-                    dataAccessor.audit(
-                            AuditElements.EventCategoryType.REST,
-                            AuditElements.AUTHENTICATION_CATEGORY,
-                            null,
-                            AuditElements.LOGIN_EVENT,
-                            Result.FAILURE,
-                            null,
-                            isAuthenticated,
-                            authentication,
-                            "User " + authentication.getPrincipal() + " not authenticated");
-                    return null;
-                }
-            });
-
-            LOG.debug("User {} not authenticated", authentication.getPrincipal());
-
-            throw new BadCredentialsException("User " + authentication.getPrincipal() + " not authenticated");
-        }
-
-        return token;
-    }
-
-    @Override
-    public boolean supports(final Class<? extends Object> type) {
-        return type.equals(UsernamePasswordAuthenticationToken.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
deleted file mode 100644
index 706bf15..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
+++ /dev/null
@@ -1,90 +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.misc.security;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.SetUtils;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.springframework.security.core.GrantedAuthority;
-
-public class SyncopeGrantedAuthority implements GrantedAuthority {
-
-    private static final long serialVersionUID = -5647624636011919735L;
-
-    private final String entitlement;
-
-    private final Set<String> realms = SetUtils.orderedSet(new HashSet<String>());
-
-    public SyncopeGrantedAuthority(final String entitlement) {
-        this.entitlement = entitlement;
-    }
-
-    public SyncopeGrantedAuthority(final String entitlement, final String realm) {
-        this.entitlement = entitlement;
-        this.realms.add(realm);
-    }
-
-    public boolean addRealm(final String newRealm) {
-        return RealmUtils.normalizingAddTo(realms, newRealm);
-    }
-
-    public void addRealms(final Collection<String> newRealms) {
-        IterableUtils.forEach(newRealms, new Closure<String>() {
-
-            @Override
-            public void execute(final String newRealm) {
-                addRealm(newRealm);
-            }
-        });
-    }
-
-    public Set<String> getRealms() {
-        return Collections.unmodifiableSet(realms);
-    }
-
-    @Override
-    public String getAuthority() {
-        return entitlement;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
-    }
-
-    @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
deleted file mode 100644
index 70ec6ac..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
+++ /dev/null
@@ -1,37 +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.misc.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-@Configurable
-public class SyncopeUserDetailsService implements UserDetailsService {
-
-    @Autowired
-    protected AuthDataAccessor dataAccessor;
-
-    @Override
-    public UserDetails loadUserByUsername(final String username) {
-        return new User(username, "<PASSWORD_PLACEHOLDER>", dataAccessor.load(username));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
deleted file mode 100644
index 5c2ab51..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
+++ /dev/null
@@ -1,83 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.Uid;
-
-class AttributeDeserializer extends JsonDeserializer<Attribute> {
-
-    @Override
-    public Attribute deserialize(final JsonParser jp, final DeserializationContext ctx)
-            throws IOException {
-
-        ObjectNode tree = jp.readValueAsTree();
-
-        String name = tree.get("name").asText();
-
-        List<Object> values = new ArrayList<Object>();
-        for (Iterator<JsonNode> itor = tree.get("value").iterator(); itor.hasNext();) {
-            JsonNode node = itor.next();
-            if (node.isNull()) {
-                values.add(null);
-            } else if (node.isObject()) {
-                values.add(((ObjectNode) node).traverse(jp.getCodec()).readValueAs(GuardedString.class));
-            } else if (node.isBoolean()) {
-                values.add(node.asBoolean());
-            } else if (node.isDouble()) {
-                values.add(node.asDouble());
-            } else if (node.isLong()) {
-                values.add(node.asLong());
-            } else if (node.isInt()) {
-                values.add(node.asInt());
-            } else {
-                String text = node.asText();
-                if (text.startsWith(AttributeSerializer.BYTE_ARRAY_PREFIX)
-                        && text.endsWith(AttributeSerializer.BYTE_ARRAY_SUFFIX)) {
-
-                    values.add(Base64.decode(StringUtils.substringBetween(
-                            text, AttributeSerializer.BYTE_ARRAY_PREFIX, AttributeSerializer.BYTE_ARRAY_SUFFIX)));
-                } else {
-                    values.add(text);
-                }
-            }
-        }
-
-        return Uid.NAME.equals(name)
-                ? new Uid(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
-                : Name.NAME.equals(name)
-                ? new Name(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
-                : AttributeBuilder.build(name, values);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
deleted file mode 100644
index 3c79c28..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
+++ /dev/null
@@ -1,73 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-
-class AttributeSerializer extends JsonSerializer<Attribute> {
-
-    public static final String BYTE_ARRAY_PREFIX = "<binary>";
-
-    public static final String BYTE_ARRAY_SUFFIX = "</binary>";
-
-    @Override
-    public void serialize(final Attribute source, final JsonGenerator jgen, final SerializerProvider sp)
-            throws IOException {
-
-        jgen.writeStartObject();
-
-        jgen.writeStringField("name", source.getName());
-
-        jgen.writeFieldName("value");
-        if (source.getValue() == null) {
-            jgen.writeNull();
-        } else {
-            jgen.writeStartArray();
-            for (Object value : source.getValue()) {
-                if (value == null) {
-                    jgen.writeNull();
-                } else if (value instanceof GuardedString) {
-                    jgen.writeObject(value);
-                } else if (value instanceof Integer) {
-                    jgen.writeNumber((Integer) value);
-                } else if (value instanceof Long) {
-                    jgen.writeNumber((Long) value);
-                } else if (value instanceof Double) {
-                    jgen.writeNumber((Double) value);
-                } else if (value instanceof Boolean) {
-                    jgen.writeBoolean((Boolean) value);
-                } else if (value instanceof byte[]) {
-                    jgen.writeString(BYTE_ARRAY_PREFIX + Base64.encode((byte[]) value) + BYTE_ARRAY_SUFFIX);
-                } else {
-                    jgen.writeString(value.toString());
-                }
-            }
-            jgen.writeEndArray();
-        }
-
-        jgen.writeEndObject();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
deleted file mode 100644
index 1cd0ec0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
+++ /dev/null
@@ -1,93 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.EncryptorFactory;
-import org.identityconnectors.common.security.GuardedString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class GuardedStringDeserializer extends JsonDeserializer<GuardedString> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(GuardedStringDeserializer.class);
-
-    @Override
-    public GuardedString deserialize(final JsonParser jp, final DeserializationContext ctx)
-            throws IOException {
-
-        ObjectNode tree = jp.readValueAsTree();
-
-        boolean readOnly = false;
-        if (tree.has("readOnly")) {
-            readOnly = tree.get("readOnly").asBoolean();
-        }
-        boolean disposed = false;
-        if (tree.has("disposed")) {
-            disposed = tree.get("disposed").asBoolean();
-        }
-        byte[] encryptedBytes = null;
-        if (tree.has("encryptedBytes")) {
-            encryptedBytes = Base64.decode(tree.get("encryptedBytes").asText());
-        }
-        String base64SHA1Hash = null;
-        if (tree.has("base64SHA1Hash")) {
-            base64SHA1Hash = tree.get("base64SHA1Hash").asText();
-        }
-
-        final byte[] clearBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(encryptedBytes);
-
-        GuardedString dest = new GuardedString(new String(clearBytes).toCharArray());
-
-        try {
-            Field field = GuardedString.class.getDeclaredField("readOnly");
-            field.setAccessible(true);
-            field.setBoolean(dest, readOnly);
-        } catch (Exception e) {
-            LOG.error("Could not set field value to {}", readOnly, e);
-        }
-
-        try {
-            Field field = GuardedString.class.getDeclaredField("disposed");
-            field.setAccessible(true);
-            field.setBoolean(dest, disposed);
-        } catch (Exception e) {
-            LOG.error("Could not set field value to {}", disposed, e);
-        }
-
-        if (base64SHA1Hash != null) {
-            try {
-                Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
-                field.setAccessible(true);
-                field.set(dest, base64SHA1Hash);
-            } catch (Exception e) {
-                LOG.error("Could not set field value to {}", base64SHA1Hash, e);
-            }
-        }
-
-        return dest;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
deleted file mode 100644
index 5c780f0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
+++ /dev/null
@@ -1,89 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.EncryptorFactory;
-import org.identityconnectors.common.security.GuardedString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class GuardedStringSerializer extends JsonSerializer<GuardedString> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(GuardedStringSerializer.class);
-
-    @Override
-    public void serialize(final GuardedString source, final JsonGenerator jgen, final SerializerProvider sp)
-            throws IOException {
-
-        jgen.writeStartObject();
-
-        boolean readOnly = false;
-        try {
-            Field field = GuardedString.class.getDeclaredField("readOnly");
-            field.setAccessible(true);
-            readOnly = field.getBoolean(source);
-        } catch (Exception e) {
-            LOG.error("Could not get field value", e);
-        }
-        jgen.writeBooleanField("readOnly", readOnly);
-
-        boolean disposed = false;
-        try {
-            Field field = GuardedString.class.getDeclaredField("disposed");
-            field.setAccessible(true);
-            disposed = field.getBoolean(source);
-        } catch (Exception e) {
-            LOG.error("Could not get field value", e);
-        }
-        jgen.writeBooleanField("disposed", disposed);
-
-        final StringBuilder cleartext = new StringBuilder();
-        source.access(new GuardedString.Accessor() {
-
-            @Override
-            public void access(final char[] clearChars) {
-                cleartext.append(clearChars);
-            }
-        });
-        byte[] encryptedBytes =
-                EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(cleartext.toString().getBytes());
-        jgen.writeStringField("encryptedBytes", Base64.encode(encryptedBytes));
-
-        String base64SHA1Hash = null;
-        try {
-            Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
-            field.setAccessible(true);
-            base64SHA1Hash = field.get(source).toString();
-        } catch (Exception e) {
-            LOG.error("Could not get field value", e);
-        }
-        if (base64SHA1Hash != null) {
-            jgen.writeStringField("base64SHA1Hash", base64SHA1Hash);
-        }
-
-        jgen.writeEndObject();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
deleted file mode 100644
index dd42568..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
+++ /dev/null
@@ -1,80 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.Version;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper class for serialization and deserialization of configuration objects (POJOs) in JSON.
- */
-public final class POJOHelper {
-
-    private static final Logger LOG = LoggerFactory.getLogger(POJOHelper.class);
-
-    private static final ObjectMapper MAPPER;
-
-    static {
-        SimpleModule pojoModule = new SimpleModule("POJOModule", new Version(1, 0, 0, null, null, null));
-        pojoModule.addSerializer(GuardedString.class, new GuardedStringSerializer());
-        pojoModule.addSerializer(Attribute.class, new AttributeSerializer());
-        pojoModule.addSerializer(SyncToken.class, new SyncTokenSerializer());
-        pojoModule.addDeserializer(GuardedString.class, new GuardedStringDeserializer());
-        pojoModule.addDeserializer(Attribute.class, new AttributeDeserializer());
-        pojoModule.addDeserializer(SyncToken.class, new SyncTokenDeserializer());
-
-        MAPPER = new ObjectMapper();
-        MAPPER.registerModule(pojoModule);
-        MAPPER.registerModule(new AfterburnerModule());
-    }
-
-    public static String serialize(final Object object) {
-        String result = null;
-
-        try {
-            result = MAPPER.writeValueAsString(object);
-        } catch (Exception e) {
-            LOG.error("During serialization", e);
-        }
-
-        return result;
-    }
-
-    public static <T extends Object> T deserialize(final String serialized, final Class<T> reference) {
-        T result = null;
-
-        try {
-            result = MAPPER.readValue(serialized, reference);
-        } catch (Exception e) {
-            LOG.error("During deserialization", e);
-        }
-
-        return result;
-    }
-
-    private POJOHelper() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java
deleted file mode 100644
index cc25ef3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import org.apache.commons.codec.binary.Base64;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-class SyncTokenDeserializer extends JsonDeserializer<SyncToken> {
-
-    @Override
-    public SyncToken deserialize(final JsonParser jp, final DeserializationContext ctx)
-            throws IOException {
-
-        ObjectNode tree = jp.readValueAsTree();
-
-        Object value = null;
-        if (tree.has("value")) {
-            JsonNode node = tree.get("value");
-            value = node.isNull()
-                    ? null
-                    : node.isBoolean()
-                            ? node.asBoolean()
-                            : node.isDouble()
-                                    ? node.asDouble()
-                                    : node.isLong()
-                                            ? node.asLong()
-                                            : node.isInt()
-                                                    ? node.asInt()
-                                                    : node.asText();
-
-            if (value instanceof String) {
-                String base64 = (String) value;
-                if (Base64.isBase64(base64)) {
-                    value = Base64.decodeBase64(base64);
-                }
-            }
-        }
-
-        return new SyncToken(value);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
deleted file mode 100644
index eb75eb2..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
+++ /dev/null
@@ -1,57 +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.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import org.apache.commons.codec.binary.Base64;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-class SyncTokenSerializer extends JsonSerializer<SyncToken> {
-
-    @Override
-    public void serialize(final SyncToken source, final JsonGenerator jgen, final SerializerProvider sp)
-            throws IOException {
-
-        jgen.writeStartObject();
-
-        jgen.writeFieldName("value");
-
-        if (source.getValue() == null) {
-            jgen.writeNull();
-        } else if (source.getValue() instanceof Boolean) {
-            jgen.writeBoolean((Boolean) source.getValue());
-        } else if (source.getValue() instanceof Double) {
-            jgen.writeNumber((Double) source.getValue());
-        } else if (source.getValue() instanceof Long) {
-            jgen.writeNumber((Long) source.getValue());
-        } else if (source.getValue() instanceof Integer) {
-            jgen.writeNumber((Integer) source.getValue());
-        } else if (source.getValue() instanceof byte[]) {
-            jgen.writeString(Base64.encodeBase64String((byte[]) source.getValue()));
-        } else {
-            jgen.writeString(source.getValue().toString());
-        }
-
-        jgen.writeEndObject();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
deleted file mode 100644
index e67dcd6..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
+++ /dev/null
@@ -1,57 +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.misc.spring;
-
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class ApplicationContextProvider implements ApplicationContextAware {
-
-    private static ConfigurableApplicationContext CTX;
-
-    private static DefaultListableBeanFactory BEAN_FACTORY;
-
-    public static ConfigurableApplicationContext getApplicationContext() {
-        return CTX;
-    }
-
-    public static DefaultListableBeanFactory getBeanFactory() {
-        return BEAN_FACTORY == null
-                ? CTX == null
-                        ? null
-                        : (DefaultListableBeanFactory) CTX.getBeanFactory()
-                : BEAN_FACTORY;
-    }
-
-    public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
-        BEAN_FACTORY = beanFactory;
-    }
-
-    /**
-     * Wiring the ApplicationContext into a static method.
-     *
-     * @param ctx Spring application context
-     */
-    @Override
-    public void setApplicationContext(final ApplicationContext ctx) {
-        CTX = (ConfigurableApplicationContext) ctx;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
deleted file mode 100644
index 5f9fd4d..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
+++ /dev/null
@@ -1,193 +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.misc.spring;
-
-import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
-import static org.springframework.beans.BeanUtils.getPropertyDescriptors;
-
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * Overrides Spring's BeanUtils not using collection setters but instead getters + addAll() / putAll(),
- * in a JAXB friendly way.
- *
- * Refer to <a href="https://issues.apache.org/jira/browse/SYNCOPE-246">SYNCOPE-246</a> for more information.
- *
- * @see org.springframework.beans.BeanUtils
- */
-public final class BeanUtils {
-
-    private BeanUtils() {
-        // Empty private constructor for static utility classes
-    }
-
-    /**
-     * Copy the property values of the given source bean into the target bean.
-     * <p>
-     * Note: The source and target classes do not have to match or even be derived
-     * from each other, as long as the properties match. Any bean properties that the
-     * source bean exposes but the target bean does not will silently be ignored.
-     * </p><p>
-     * This is just a convenience method. For more complex transfer needs,
-     * consider using a full BeanWrapper.
-     * </p>
-     *
-     * @param source the source bean
-     * @param target the target bean
-     * @see org.springframework.beans.BeanWrapper
-     */
-    public static void copyProperties(final Object source, final Object target) {
-        copyProperties(source, target, null, (String[]) null);
-    }
-
-    /**
-     * Copy the property values of the given source bean into the given target bean,
-     * only setting properties defined in the given "editable" class (or interface).
-     * <p>
-     * Note: The source and target classes do not have to match or even be derived
-     * from each other, as long as the properties match. Any bean properties that the
-     * source bean exposes but the target bean does not will silently be ignored.
-     * </p><p>
-     * This is just a convenience method. For more complex transfer needs,
-     * consider using a full BeanWrapper.
-     * </p>
-     *
-     * @param source the source bean
-     * @param target the target bean
-     * @param editable the class (or interface) to restrict property setting to
-     * @see org.springframework.beans.BeanWrapper
-     */
-    public static void copyProperties(final Object source, final Object target, final Class<?> editable) {
-        copyProperties(source, target, editable, (String[]) null);
-    }
-
-    /**
-     * Copy the property values of the given source bean into the given target bean,
-     * ignoring the given "ignoreProperties".
-     * <p>
-     * Note: The source and target classes do not have to match or even be derived
-     * from each other, as long as the properties match. Any bean properties that the
-     * source bean exposes but the target bean does not will silently be ignored.
-     * </p><p>
-     * This is just a convenience method. For more complex transfer needs,
-     * consider using a full BeanWrapper.
-     * </p>
-     *
-     * @param source the source bean
-     * @param target the target bean
-     * @param ignoreProperties array of property names to ignore
-     * @see org.springframework.beans.BeanWrapper
-     */
-    public static void copyProperties(final Object source, final Object target, final String... ignoreProperties) {
-        copyProperties(source, target, null, ignoreProperties);
-    }
-
-    /**
-     * Copy the property values of the given source bean into the given target bean.
-     * <p>
-     * Note: The source and target classes do not have to match or even be derived
-     * from each other, as long as the properties match. Any bean properties that the
-     * source bean exposes but the target bean does not will silently be ignored.
-     * </p>
-     *
-     * @param source the source bean
-     * @param target the target bean
-     * @param editable the class (or interface) to restrict property setting to
-     * @param ignoreProperties array of property names to ignore
-     * @see org.springframework.beans.BeanWrapper
-     */
-    @SuppressWarnings("unchecked")
-    private static void copyProperties(
-            final Object source, final Object target, final Class<?> editable, final String... ignoreProperties) {
-
-        Assert.notNull(source, "Source must not be null");
-        Assert.notNull(target, "Target must not be null");
-
-        Class<?> actualEditable = target.getClass();
-        if (editable != null) {
-            if (!editable.isInstance(target)) {
-                throw new IllegalArgumentException("Target class [" + target.getClass().getName()
-                        + "] not assignable to Editable class [" + editable.getName() + "]");
-            }
-            actualEditable = editable;
-        }
-        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
-        List<String> ignoreList = (ignoreProperties == null)
-                ? Collections.<String>emptyList() : Arrays.asList(ignoreProperties);
-
-        for (PropertyDescriptor targetPd : targetPds) {
-            if (ignoreProperties == null || (!ignoreList.contains(targetPd.getName()))) {
-                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
-                if (sourcePd != null) {
-                    Method readMethod = sourcePd.getReadMethod();
-                    if (readMethod != null) {
-                        Method writeMethod = targetPd.getWriteMethod();
-
-                        try {
-                            // Diverts from Spring's BeanUtils: if no write method is found and property is collection,
-                            // try to use addAll() / putAll().
-                            if (writeMethod == null) {
-                                Object value = readMethod.invoke(source);
-                                Method targetReadMethod = targetPd.getReadMethod();
-                                if (targetReadMethod != null) {
-                                    if (!Modifier.isPublic(targetReadMethod.getDeclaringClass().getModifiers())) {
-                                        targetReadMethod.setAccessible(true);
-                                    }
-                                    Object destValue = targetReadMethod.invoke(target);
-
-                                    if (value instanceof Collection && destValue instanceof Collection) {
-                                        ((Collection) destValue).clear();
-                                        ((Collection) destValue).addAll((Collection) value);
-                                    } else if (value instanceof Map && destValue instanceof Map) {
-                                        ((Map) destValue).clear();
-                                        ((Map) destValue).putAll((Map) value);
-                                    }
-                                }
-                            } else if (ClassUtils.isAssignable(
-                                    writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
-
-                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
-                                    readMethod.setAccessible(true);
-                                }
-                                Object value = readMethod.invoke(source);
-                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
-                                    writeMethod.setAccessible(true);
-                                }
-                                writeMethod.invoke(target, value);
-                            }
-                        } catch (Throwable ex) {
-                            throw new FatalBeanException(
-                                    "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
deleted file mode 100644
index d91a60f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
+++ /dev/null
@@ -1,65 +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.misc.spring;
-
-import javax.servlet.ServletException;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.core.PriorityOrdered;
-import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
-import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
-
-/**
- * Removes the limitation of having Spring security roles to be prefixed with 'ROLE_'.
- */
-public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
-
-    @Override
-    public Object postProcessAfterInitialization(final Object bean, final String beanName) {
-        if (bean instanceof DefaultMethodSecurityExpressionHandler) {
-            ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
-        }
-        if (bean instanceof DefaultWebSecurityExpressionHandler) {
-            ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
-        }
-        if (bean instanceof SecurityContextHolderAwareRequestFilter) {
-            SecurityContextHolderAwareRequestFilter filter = (SecurityContextHolderAwareRequestFilter) bean;
-            filter.setRolePrefix(StringUtils.EMPTY);
-            try {
-                filter.afterPropertiesSet();
-            } catch (ServletException e) {
-                throw new FatalBeanException(e.getMessage(), e);
-            }
-        }
-
-        return bean;
-    }
-
-    @Override
-    public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
-        return bean;
-    }
-
-    @Override
-    public int getOrder() {
-        return PriorityOrdered.HIGHEST_PRECEDENCE;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java
deleted file mode 100644
index e239002..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.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.misc.spring;
-
-import java.lang.reflect.Method;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
-import org.springframework.transaction.interceptor.TransactionAttribute;
-import org.springframework.transaction.interceptor.TransactionAttributeSource;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
-
-/**
- * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
- * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
- * {@link AuthContextUtils#getDomain()}.
- */
-public class DomainTransactionInterceptor extends TransactionInterceptor {
-
-    private static final long serialVersionUID = 5113728988680448551L;
-
-    private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
-
-    @Override
-    public TransactionAttributeSource getTransactionAttributeSource() {
-        final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
-
-        return new TransactionAttributeSource() {
-
-            @Override
-            public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
-                TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
-
-                if (txAttr instanceof DefaultTransactionAttribute) {
-                    ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
-                }
-
-                return txAttr;
-            }
-        };
-    }
-
-    @Override
-    public Object invoke(final MethodInvocation invocation) throws Throwable {
-        try {
-            return super.invoke(invocation);
-        } catch (Throwable e) {
-            LOG.debug("Error during {} invocation", invocation.getMethod(), e);
-            throw e;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java
deleted file mode 100644
index d9d772b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.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.misc.spring;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
-
-/**
- * Replaces Spring's {@link TransactionInterceptor} with {@link DomainTransactionInterceptor}.
- */
-public class DomainTransactionInterceptorInjector implements BeanFactoryPostProcessor {
-
-    @Override
-    public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
-        BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
-        bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
deleted file mode 100644
index 0fdc116..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
+++ /dev/null
@@ -1,82 +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.misc.spring;
-
-import java.io.IOException;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.ArrayUtils;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.io.support.ResourcePatternResolver;
-
-public class ResourceWithFallbackLoader implements ResourceLoaderAware, ResourcePatternResolver {
-
-    private ResourcePatternResolver resolver;
-
-    private String primary;
-
-    private String fallback;
-
-    @Override
-    public void setResourceLoader(final ResourceLoader resourceLoader) {
-        this.resolver = (ResourcePatternResolver) resourceLoader;
-    }
-
-    public void setPrimary(final String primary) {
-        this.primary = primary;
-    }
-
-    public void setFallback(final String fallback) {
-        this.fallback = fallback;
-    }
-
-    @Override
-    public Resource getResource(final String location) {
-        Resource resource = resolver.getResource(primary + location);
-        if (!resource.exists()) {
-            resource = resolver.getResource(fallback + location);
-        }
-
-        return resource;
-    }
-
-    public Resource getResource() {
-        return getResource(StringUtils.EMPTY);
-    }
-
-    @Override
-    public Resource[] getResources(final String locationPattern) throws IOException {
-        Resource[] resources = resolver.getResources(primary + locationPattern);
-        if (ArrayUtils.isEmpty(resources)) {
-            resources = resolver.getResources(fallback + locationPattern);
-        }
-
-        return resources;
-    }
-
-    public Resource[] getResources() throws IOException {
-        return getResources(StringUtils.EMPTY);
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return resolver.getClassLoader();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
deleted file mode 100644
index 667a28e..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
+++ /dev/null
@@ -1,267 +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.misc.utils;
-
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.security.SecureRandomUtils;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-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.misc.security.Encryptor;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-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.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedByteArray;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-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;
-
-@Component
-public class ConnObjectUtils {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtils.class);
-
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
-    @Autowired
-    private TemplateUtils templateUtils;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private PasswordGenerator passwordGenerator;
-
-    @Autowired
-    private MappingUtils mappingUtils;
-
-    /**
-     * Extract password value from passed value (if instance of GuardedString or GuardedByteArray).
-     *
-     * @param pwd received from the underlying connector
-     * @return password value
-     */
-    public static String getPassword(final Object pwd) {
-        final StringBuilder result = new StringBuilder();
-
-        if (pwd instanceof GuardedString) {
-            ((GuardedString) pwd).access(new GuardedString.Accessor() {
-
-                @Override
-                public void access(final char[] clearChars) {
-                    result.append(clearChars);
-                }
-            });
-        } else if (pwd instanceof GuardedByteArray) {
-            ((GuardedByteArray) pwd).access(new GuardedByteArray.Accessor() {
-
-                @Override
-                public void access(final byte[] clearBytes) {
-                    result.append(new String(clearBytes));
-                }
-            });
-        } else if (pwd instanceof String) {
-            result.append((String) pwd);
-        } else {
-            result.append(pwd.toString());
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
-     *
-     * @param obj connector object
-     * @param syncTask synchronization task
-     * @param provision provision information
-     * @param anyUtils utils
-     * @param <T> any object
-     * @return UserTO for the user to be created
-     */
-    @Transactional(readOnly = true)
-    public <T extends AnyTO> T getAnyTO(
-            final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
-
-        T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
-
-        // (for users) if password was not set above, generate
-        if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
-            final UserTO userTO = (UserTO) anyTO;
-
-            List<PasswordRuleConf> ruleConfs = new ArrayList<>();
-
-            Realm realm = realmDAO.find(userTO.getRealm());
-            if (realm != null) {
-                for (Realm ancestor : realmDAO.findAncestors(realm)) {
-                    if (ancestor.getPasswordPolicy() != null) {
-                        ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
-                    }
-                }
-            }
-
-            for (String resName : userTO.getResources()) {
-                ExternalResource resource = resourceDAO.find(resName);
-                if (resource != null && resource.getPasswordPolicy() != null) {
-                    ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
-                }
-            }
-
-            String password;
-            try {
-                password = passwordGenerator.generate(ruleConfs);
-            } catch (InvalidPasswordRuleConf e) {
-                LOG.error("Could not generate policy-compliant random password for {}", userTO, e);
-
-                password = SecureRandomUtils.generateRandomPassword(16);
-            }
-            userTO.setPassword(password);
-        }
-
-        return anyTO;
-    }
-
-    /**
-     * Build {@link AnyPatch} out of connector object attributes and schema mapping.
-     *
-     * @param key any object to be updated
-     * @param obj connector object
-     * @param original any object to get diff from
-     * @param syncTask synchronization task
-     * @param provision provision information
-     * @param anyUtils utils
-     * @param <T> any object
-     * @return modifications for the any object to be updated
-     */
-    @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) {
-
-        AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
-        updated.setKey(key);
-
-        if (null != anyUtils.getAnyTypeKind()) {
-            switch (anyUtils.getAnyTypeKind()) {
-                case USER:
-                    // update password if and only if password is really changed
-                    User user = userDAO.authFind(key);
-                    if (StringUtils.isBlank(((UserTO) updated).getPassword())
-                            || ENCRYPTOR.verify(((UserTO) updated).getPassword(),
-                                    user.getCipherAlgorithm(), user.getPassword())) {
-
-                        ((UserTO) updated).setPassword(null);
-                    }
-                    return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
-
-                case GROUP:
-                    return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
-
-                case ANY_OBJECT:
-                    return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
-
-                default:
-            }
-        }
-
-        return null;
-    }
-
-    private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
-            final SyncTask syncTask, 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 : MappingUtils.getSyncMappingItems(provision)) {
-            mappingUtils.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
-        }
-
-        // 2. add data from defined template (if any)
-        templateUtils.apply(anyTO, syncTask.getTemplate(provision.getAnyType()));
-
-        return anyTO;
-    }
-
-    /**
-     * Get connector object TO from a connector object.
-     *
-     * @param connObject connector object.
-     * @return connector object TO.
-     */
-    public ConnObjectTO getConnObjectTO(final ConnectorObject connObject) {
-        final ConnObjectTO connObjectTO = new ConnObjectTO();
-
-        if (connObject != null) {
-            for (Attribute attr : connObject.getAttributes()) {
-                AttrTO attrTO = new AttrTO();
-                attrTO.setSchema(attr.getName());
-
-                if (attr.getValue() != null) {
-                    for (Object value : attr.getValue()) {
-                        if (value != null) {
-                            if (value instanceof GuardedString || value instanceof GuardedByteArray) {
-                                attrTO.getValues().add(getPassword(value));
-                            } else if (value instanceof byte[]) {
-                                attrTO.getValues().add(Base64.encode((byte[]) value));
-                            } else {
-                                attrTO.getValues().add(value.toString());
-                            }
-                        }
-                    }
-                }
-
-                connObjectTO.getPlainAttrs().add(attrTO);
-            }
-        }
-
-        return connObjectTO;
-    }
-}


[17/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
Further refactoring as per SYNCOPE-620


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

Branch: refs/heads/master
Commit: 28569df55015aa2ac86ac21020005d0e8fb4addf
Parents: 0d09829
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Mar 8 16:12:14 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Mar 9 12:41:12 2016 +0100

----------------------------------------------------------------------
 archetype/pom.xml                               |   2 +-
 .../syncope/core/logic/AbstractAnyLogic.java    |   8 +-
 .../syncope/core/logic/AnyObjectLogic.java      |   4 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java |   2 +-
 .../syncope/core/logic/ConfigurationLogic.java  |   2 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   6 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |   6 +-
 .../core/logic/LogicInvocationHandler.java      |   2 +-
 .../syncope/core/logic/ResourceLogic.java       |  16 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |   4 +-
 .../apache/syncope/core/logic/UserLogic.java    |   4 +-
 .../init/ClassPathScanImplementationLookup.java |  12 +-
 .../core/logic/init/EntitlementAccessor.java    |   2 +-
 .../core/logic/init/EntitlementLoader.java      |   4 +-
 .../syncope/core/logic/init/JobManagerImpl.java |   8 +-
 .../syncope/core/logic/init/LoggerAccessor.java |   2 +-
 .../syncope/core/logic/init/LoggerLoader.java   |   9 +-
 .../core/logic/init/LogicInitializer.java       |   2 +-
 .../logic/notification/NotificationJob.java     |   2 +-
 .../notification/NotificationJobDelegate.java   |   4 +-
 .../core/logic/report/AuditReportlet.java       |   6 +-
 .../core/logic/report/GroupReportlet.java       |   2 +-
 .../logic/report/ReconciliationReportlet.java   |  24 +-
 .../syncope/core/logic/report/ReportJob.java    |   2 +-
 .../core/logic/report/ReportJobDelegate.java    |   4 +-
 .../core/logic/report/StaticReportlet.java      |   2 +-
 .../core/logic/report/UserReportlet.java        |   4 +-
 core/misc/pom.xml                               | 137 ---
 .../apache/syncope/core/misc/AuditEntry.java    |  77 --
 .../apache/syncope/core/misc/AuditManager.java  |  79 --
 .../syncope/core/misc/EntitlementsHolder.java   |  72 --
 .../core/misc/jexl/ClassFreeUberspect.java      |  41 -
 .../core/misc/jexl/EmptyClassLoader.java        |  36 -
 .../syncope/core/misc/jexl/JexlUtils.java       | 241 ------
 .../misc/policy/AccountPolicyException.java     |  32 -
 .../misc/policy/InvalidPasswordRuleConf.java    |  37 -
 .../misc/policy/PasswordPolicyException.java    |  32 -
 .../core/misc/policy/PolicyException.java       |  32 -
 .../syncope/core/misc/policy/PolicyPattern.java |  50 --
 .../core/misc/search/SearchCondConverter.java   |  64 --
 .../core/misc/search/SearchCondVisitor.java     | 222 -----
 .../core/misc/security/AuthContextUtils.java    | 126 ---
 .../core/misc/security/AuthDataAccessor.java    | 318 -------
 .../misc/security/DefaultPasswordGenerator.java | 334 --------
 .../DelegatedAdministrationException.java       |  33 -
 .../syncope/core/misc/security/Encryptor.java   | 256 ------
 .../misc/security/MustChangePasswordFilter.java |  80 --
 .../core/misc/security/PasswordGenerator.java   |  32 -
 .../core/misc/security/SecureRandomUtils.java   |  48 --
 .../security/SyncopeAccessDeniedHandler.java    |  43 -
 .../security/SyncopeAuthenticationDetails.java  |  86 --
 .../SyncopeAuthenticationDetailsSource.java     |  32 -
 .../SyncopeAuthenticationEntryPoint.java        |  43 -
 .../security/SyncopeAuthenticationProvider.java | 210 -----
 .../misc/security/SyncopeGrantedAuthority.java  |  90 --
 .../security/SyncopeUserDetailsService.java     |  37 -
 .../serialization/AttributeDeserializer.java    |  83 --
 .../misc/serialization/AttributeSerializer.java |  73 --
 .../GuardedStringDeserializer.java              |  93 --
 .../serialization/GuardedStringSerializer.java  |  89 --
 .../core/misc/serialization/POJOHelper.java     |  80 --
 .../serialization/SyncTokenDeserializer.java    |  64 --
 .../misc/serialization/SyncTokenSerializer.java |  57 --
 .../misc/spring/ApplicationContextProvider.java |  57 --
 .../syncope/core/misc/spring/BeanUtils.java     | 193 -----
 .../spring/DefaultRolesPrefixPostProcessor.java |  65 --
 .../spring/DomainTransactionInterceptor.java    |  70 --
 .../DomainTransactionInterceptorInjector.java   |  38 -
 .../misc/spring/ResourceWithFallbackLoader.java |  82 --
 .../core/misc/utils/ConnObjectUtils.java        | 267 ------
 .../syncope/core/misc/utils/EntityUtils.java    |  41 -
 .../core/misc/utils/ExceptionUtils2.java        |  47 -
 .../syncope/core/misc/utils/FormatUtils.java    | 121 ---
 .../syncope/core/misc/utils/MappingUtils.java   | 841 ------------------
 .../syncope/core/misc/utils/RealmUtils.java     |  63 --
 .../syncope/core/misc/utils/TemplateUtils.java  | 224 -----
 .../misc/src/main/resources/security.properties |  32 -
 .../misc/src/main/resources/securityContext.xml |  95 ---
 core/misc/src/main/resources/utilsContext.xml   |  32 -
 .../misc/search/SearchCondConverterTest.java    | 226 -----
 .../core/misc/security/EncryptorTest.java       |  58 --
 .../misc/security/PasswordGeneratorTest.java    | 144 ----
 core/persistence-api/pom.xml                    |  13 +
 .../api/search/SearchCondConverter.java         |  64 ++
 .../api/search/SearchCondVisitor.java           | 222 +++++
 .../api/search/SearchCondConverterTest.java     | 226 +++++
 core/persistence-jpa/pom.xml                    |  14 +-
 .../jpa/content/ContentLoaderHandler.java       |   2 +-
 .../jpa/content/XMLContentExporter.java         |   4 +-
 .../jpa/content/XMLContentLoader.java           |   4 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |   4 +-
 .../persistence/jpa/dao/DefaultAccountRule.java |   2 +-
 .../jpa/dao/DefaultPasswordRule.java            |   4 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |   8 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |   4 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   8 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |   2 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  10 +-
 .../persistence/jpa/entity/AbstractAny.java     |   2 +-
 .../jpa/entity/AbstractPlainAttrValue.java      |   4 +-
 .../jpa/entity/AnnotatedEntityListener.java     |   2 +-
 .../jpa/entity/JPAAnyUtilsFactory.java          |   2 +-
 .../persistence/jpa/entity/JPAConnInstance.java |   2 +-
 .../core/persistence/jpa/entity/JPADomain.java  |   2 +-
 .../jpa/entity/JPAReportletConfInstance.java    |   2 +-
 .../persistence/jpa/entity/group/JPAGroup.java  |   2 +-
 .../jpa/entity/policy/JPAAccountPolicy.java     |   2 +-
 .../policy/JPAAccountRuleConfInstance.java      |   2 +-
 .../policy/JPAPasswordRuleConfInstance.java     |   2 +-
 .../jpa/entity/policy/JPAPushPolicy.java        |   2 +-
 .../jpa/entity/policy/JPASyncPolicy.java        |   2 +-
 .../entity/resource/AbstractAnyTemplate.java    |   2 +-
 .../entity/resource/JPAExternalResource.java    |   2 +-
 .../jpa/entity/resource/JPAProvision.java       |   2 +-
 .../jpa/entity/task/JPAPropagationTask.java     |   2 +-
 .../persistence/jpa/entity/user/JPAUser.java    |   6 +-
 .../spring/DomainTransactionInterceptor.java    |  70 ++
 .../DomainTransactionInterceptorInjector.java   |  38 +
 .../entity/ConnInstanceValidator.java           |   4 +-
 .../entity/EntityValidationListener.java        |   2 +-
 .../entity/ExternalResourceValidator.java       |   2 +-
 .../entity/ProvisioningTaskValidator.java       |   6 +-
 .../src/main/resources/domains.xml              |   2 +-
 .../src/main/resources/domains/MasterDomain.xml |   4 +-
 .../src/main/resources/persistenceContext.xml   |   4 +-
 .../core/persistence/jpa/AbstractTest.java      |   4 +-
 .../persistence/jpa/inner/MultitenancyTest.java |   4 +-
 .../persistence/jpa/inner/PlainAttrTest.java    |   2 +-
 .../core/persistence/jpa/inner/PolicyTest.java  |   2 +-
 .../core/persistence/jpa/inner/UserTest.java    |   4 +-
 .../core/persistence/jpa/outer/GroupTest.java   |   2 +-
 .../core/persistence/jpa/outer/RoleTest.java    |   2 +-
 .../core/persistence/jpa/outer/TaskTest.java    |   2 +-
 .../test/resources/domains/MasterContent.xml    |   2 +-
 .../src/test/resources/domains/TwoDomain.xml    |   4 +-
 .../src/test/resources/persistenceTest.xml      |   7 +-
 core/pom.xml                                    |   2 +-
 core/provisioning-api/pom.xml                   |  13 +
 .../core/provisioning/api/AuditManager.java     |  35 +
 .../provisioning/api/ConnPoolConfUtils.java     |  69 --
 .../core/provisioning/api/Connector.java        |   2 +-
 .../provisioning/api/EntitlementsHolder.java    |  72 ++
 .../core/provisioning/api/MappingManager.java   |  78 ++
 .../syncope/core/provisioning/api/URIUtils.java |  61 --
 .../api/UserProvisioningManager.java            |   2 +-
 .../serialization/AttributeDeserializer.java    |  83 ++
 .../api/serialization/AttributeSerializer.java  |  73 ++
 .../GuardedStringDeserializer.java              |  93 ++
 .../serialization/GuardedStringSerializer.java  |  89 ++
 .../api/serialization/POJOHelper.java           |  80 ++
 .../serialization/SyncTokenDeserializer.java    |  66 ++
 .../api/serialization/SyncTokenSerializer.java  |  57 ++
 .../api/sync/AnyObjectPushResultHandler.java    |  23 -
 .../api/sync/AnyObjectSyncResultHandler.java    |  23 -
 .../api/sync/GroupPushResultHandler.java        |  23 -
 .../api/sync/GroupSyncResultHandler.java        |  26 -
 .../api/sync/IgnoreProvisionException.java      |  29 -
 .../api/sync/ProvisioningActions.java           |  40 -
 .../api/sync/ProvisioningProfile.java           |  81 --
 .../api/sync/ProvisioningReport.java            | 140 ---
 .../core/provisioning/api/sync/PushActions.java | 163 ----
 .../api/sync/ReconciliationFilterBuilder.java   |  30 -
 .../core/provisioning/api/sync/SyncActions.java | 203 -----
 .../api/sync/SyncCorrelationRule.java           |  36 -
 .../api/sync/SyncopePushResultHandler.java      |  26 -
 .../api/sync/SyncopeResultHandler.java          |  29 -
 .../api/sync/SyncopeSyncResultHandler.java      |  29 -
 .../api/sync/UserPushResultHandler.java         |  23 -
 .../api/sync/UserSyncResultHandler.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 +
 .../api/utils/ConnPoolConfUtils.java            |  69 ++
 .../provisioning/api/utils/EntityUtils.java     |  41 +
 .../provisioning/api/utils/ExceptionUtils2.java |  47 +
 .../provisioning/api/utils/FormatUtils.java     | 121 +++
 .../core/provisioning/api/utils/RealmUtils.java |  63 ++
 .../core/provisioning/api/utils/URIUtils.java   |  61 ++
 .../utils/policy/AccountPolicyException.java    |  32 +
 .../utils/policy/InvalidPasswordRuleConf.java   |  37 +
 .../utils/policy/PasswordPolicyException.java   |  32 +
 .../api/utils/policy/PolicyException.java       |  32 +
 .../api/utils/policy/PolicyPattern.java         |  50 ++
 core/provisioning-java/pom.xml                  |   7 +-
 .../core/provisioning/java/AuditEntry.java      |  77 ++
 .../provisioning/java/AuditManagerImpl.java     |  81 ++
 .../java/ConnIdBundleManagerImpl.java           |   2 +-
 .../provisioning/java/ConnectorFacadeProxy.java |   9 +-
 .../provisioning/java/ConnectorManager.java     |   4 +-
 .../DefaultAnyObjectProvisioningManager.java    |   2 +-
 .../java/DefaultGroupProvisioningManager.java   |   2 +-
 .../java/DefaultUserProvisioningManager.java    |   4 +-
 .../provisioning/java/DerAttrHandlerImpl.java   |   2 +-
 .../provisioning/java/MappingManagerImpl.java   | 847 +++++++++++++++++++
 .../provisioning/java/VirAttrHandlerImpl.java   |  13 +-
 .../java/data/AbstractAnyDataBinder.java        |  20 +-
 .../java/data/AnyObjectDataBinderImpl.java      |   4 +-
 .../java/data/ConfigurationDataBinderImpl.java  |   2 +-
 .../java/data/ConnInstanceDataBinderImpl.java   |   4 +-
 .../java/data/GroupDataBinderImpl.java          |   2 +-
 .../java/data/NotificationDataBinderImpl.java   |   2 +-
 .../java/data/RealmDataBinderImpl.java          |   2 +-
 .../java/data/ReportDataBinderImpl.java         |   2 +-
 .../java/data/ResourceDataBinderImpl.java       |   4 +-
 .../java/data/RoleDataBinderImpl.java           |   2 +-
 .../java/data/SchemaDataBinderImpl.java         |   4 +-
 .../data/SecurityQuestionDataBinderImpl.java    |   2 +-
 .../java/data/TaskDataBinderImpl.java           |   8 +-
 .../java/data/UserDataBinderImpl.java           |   8 +-
 .../java/jexl/ClassFreeUberspect.java           |  41 +
 .../java/jexl/EmptyClassLoader.java             |  36 +
 .../core/provisioning/java/jexl/JexlUtils.java  | 241 ++++++
 .../java/job/AbstractInterruptableJob.java      |   2 +-
 .../java/job/AbstractSchedTaskJobDelegate.java  |   4 +-
 .../core/provisioning/java/job/TaskJob.java     |   4 +-
 .../notification/NotificationManagerImpl.java   |   6 +-
 .../AbstractPropagationTaskExecutor.java        |  17 +-
 .../propagation/DefaultPropagationReporter.java |   2 +-
 .../LDAPMembershipPropagationActions.java       |   2 +-
 .../PriorityPropagationTaskExecutor.java        |   2 +-
 .../propagation/PropagationManagerImpl.java     |  13 +-
 .../PropagationTaskCallableImpl.java            |   4 +-
 .../sync/AbstractProvisioningJobDelegate.java   | 434 ----------
 .../java/sync/AbstractPushResultHandler.java    | 434 ----------
 .../java/sync/AbstractSyncResultHandler.java    | 797 -----------------
 .../java/sync/AbstractSyncopeResultHandler.java | 155 ----
 .../sync/AnyObjectPushResultHandlerImpl.java    |  70 --
 .../sync/AnyObjectSyncResultHandlerImpl.java    | 112 ---
 .../java/sync/DBPasswordSyncActions.java        | 142 ----
 .../java/sync/DefaultPushActions.java           | 100 ---
 .../DefaultReconciliationFilterBuilder.java     |  38 -
 .../java/sync/DefaultSyncActions.java           | 121 ---
 .../java/sync/GroupPushResultHandlerImpl.java   |  70 --
 .../java/sync/GroupSyncResultHandlerImpl.java   | 138 ---
 .../java/sync/LDAPMembershipSyncActions.java    | 335 --------
 .../java/sync/LDAPPasswordSyncActions.java      | 124 ---
 .../sync/PlainAttrsSyncCorrelationRule.java     | 115 ---
 .../provisioning/java/sync/PushJobDelegate.java | 206 -----
 .../provisioning/java/sync/SyncJobDelegate.java | 251 ------
 .../core/provisioning/java/sync/SyncUtils.java  | 318 -------
 .../java/sync/UserPushResultHandlerImpl.java    |  96 ---
 .../java/sync/UserSyncResultHandlerImpl.java    | 133 ---
 .../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             | 269 ++++++
 .../provisioning/java/utils/TemplateUtils.java  | 224 +++++
 .../core/provisioning/java/AbstractTest.java    |   1 -
 .../provisioning/java/ConnectorManagerTest.java |   2 +-
 .../provisioning/java/MailTemplateTest.java     |   2 +-
 .../core/provisioning/java/MappingTest.java     |   5 +-
 .../syncope/core/rest/cxf/AddDomainFilter.java  |   2 +-
 .../rest/cxf/RestServiceExceptionMapper.java    |   2 +-
 .../rest/cxf/ThreadLocalCleanupListener.java    |   2 +-
 .../rest/cxf/service/AbstractServiceImpl.java   |   2 +-
 core/spring/pom.xml                             | 103 +++
 .../core/spring/ApplicationContextProvider.java |  57 ++
 .../apache/syncope/core/spring/BeanUtils.java   | 193 +++++
 .../spring/DefaultRolesPrefixPostProcessor.java |  65 ++
 .../core/spring/ResourceWithFallbackLoader.java |  82 ++
 .../core/spring/security/AuthContextUtils.java  | 126 +++
 .../core/spring/security/AuthDataAccessor.java  | 319 +++++++
 .../security/DefaultPasswordGenerator.java      | 334 ++++++++
 .../DelegatedAdministrationException.java       |  33 +
 .../syncope/core/spring/security/Encryptor.java | 256 ++++++
 .../security/MustChangePasswordFilter.java      |  80 ++
 .../core/spring/security/PasswordGenerator.java |  32 +
 .../core/spring/security/SecureRandomUtils.java |  48 ++
 .../security/SyncopeAccessDeniedHandler.java    |  43 +
 .../security/SyncopeAuthenticationDetails.java  |  86 ++
 .../SyncopeAuthenticationDetailsSource.java     |  32 +
 .../SyncopeAuthenticationEntryPoint.java        |  43 +
 .../security/SyncopeAuthenticationProvider.java | 210 +++++
 .../security/SyncopeGrantedAuthority.java       |  90 ++
 .../security/SyncopeUserDetailsService.java     |  37 +
 .../src/main/resources/security.properties      |  32 +
 .../src/main/resources/securityContext.xml      |  96 +++
 .../core/spring/security/EncryptorTest.java     |  60 ++
 .../spring/security/PasswordGeneratorTest.java  | 146 ++++
 core/workflow-activiti/pom.xml                  |   2 +-
 .../activiti/ActivitiDefinitionLoader.java      |   2 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |   4 +-
 .../activiti/spring/DomainProcessEngine.java    |   2 +-
 .../main/resources/workflowActivitiContext.xml  |   2 +-
 deb/core/pom.xml                                |   2 +-
 .../core/logic/init/CamelRouteLoader.java       |   4 +-
 .../camel/CamelUserProvisioningManager.java     |   2 +-
 .../provisioning/camel/SyncopeCamelContext.java |   2 +-
 .../camel/data/CamelRouteDataBinderImpl.java    |   2 +-
 .../processor/AnyObjectCreateProcessor.java     |   2 +-
 .../processor/AnyObjectDeleteProcessor.java     |   2 +-
 .../AnyObjectDeprovisionProcessor.java          |   2 +-
 .../processor/AnyObjectProvisionProcessor.java  |   2 +-
 .../processor/AnyObjectUpdateProcessor.java     |   2 +-
 .../processor/GroupCreateInSyncProcessor.java   |   2 +-
 .../camel/processor/GroupCreateProcessor.java   |   2 +-
 .../camel/processor/GroupDeleteProcessor.java   |   2 +-
 .../processor/GroupDeprovisionProcessor.java    |   2 +-
 .../processor/GroupProvisionProcessor.java      |   2 +-
 .../camel/processor/GroupUpdateProcessor.java   |   2 +-
 .../processor/UserConfirmPwdResetProcessor.java |   2 +-
 .../camel/processor/UserCreateProcessor.java    |   2 +-
 .../camel/processor/UserDeleteProcessor.java    |   2 +-
 .../processor/UserDeprovisionProcessor.java     |   2 +-
 .../camel/processor/UserProvisionProcessor.java |   2 +-
 .../UserStatusPropagationProcessor.java         |   2 +-
 .../processor/UserUpdateInSyncProcessor.java    |   2 +-
 .../camel/processor/UserUpdateProcessor.java    |   2 +-
 .../main/resources/provisioningCamelContext.xml |   6 +-
 fit/core-reference/pom.xml                      |   5 +-
 .../fit/core/reference/TestAccountRule.java     |   2 +-
 .../fit/core/reference/TestPasswordRule.java    |   2 +-
 .../TestReconciliationFilterBuilder.java        |   2 +-
 .../fit/core/reference/TestSyncActions.java     |   6 +-
 .../fit/core/reference/TestSyncRule.java        |   2 +-
 .../src/main/resources/coreContext.xml          |   2 +-
 .../resources/jboss/domains/MasterDomain.xml    |   4 +-
 .../main/resources/jboss/domains/TwoDomain.xml  |   4 +-
 .../src/main/webapp/cacheStats.jsp              |   2 +-
 .../syncope/fit/core/AuthenticationITCase.java  |   2 +-
 .../apache/syncope/fit/core/SyncTaskITCase.java |   6 +-
 .../org/apache/syncope/fit/core/UserITCase.java |   2 +-
 fit/enduser-reference/pom.xml                   |   2 +-
 354 files changed, 11814 insertions(+), 11729 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/archetype/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/pom.xml b/archetype/pom.xml
index 93e2202..b295c81 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -153,7 +153,7 @@ under the License.
         </excludes>
       </resource>
       <resource>
-        <directory>../core/misc/src/main/resources</directory>
+        <directory>../core/spring/src/main/resources</directory>
         <includes>
           <include>security.properties</include>
         </includes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index f108052..42701e0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -37,10 +37,10 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 37392a2..b74cd4f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -38,13 +38,13 @@ import org.apache.syncope.common.lib.types.AnyEntitlement;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 697fb07..19129d1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
index 5f2ef24..98e1032 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
@@ -23,7 +23,7 @@ import java.lang.reflect.Method;
 import java.util.List;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 0e9850b..344675c 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -41,7 +41,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PatchOperation;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 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;
@@ -49,8 +49,8 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 7b2842d..adb33d0 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
@@ -56,9 +56,9 @@ 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.Logger;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
index 77ff7b5..63d1689 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 8825e67..da51c71 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -49,8 +49,8 @@ import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
@@ -61,6 +61,7 @@ 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.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -104,7 +105,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private ConnObjectUtils connObjectUtils;
 
     @Autowired
-    private MappingUtils mappingUtils;
+    private MappingManager mappingManager;
 
     @Autowired
     private ConnectorFactory connFactory;
@@ -228,12 +229,12 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         }
 
         // 2. build connObjectKeyItem
-        MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(init.getRight());
+        MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(init.getRight());
         if (connObjectKeyItem == null) {
             throw new NotFoundException(
                     "ConnObjectKey mapping for " + init.getMiddle() + " " + anyKey + " on resource '" + key + "'");
         }
-        String connObjectKeyValue = mappingUtils.getConnObjectKeyValue(any, init.getRight());
+        String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, init.getRight());
 
         // 3. determine attributes to query
         Set<MappingItem> linkinMappingItems = new HashSet<>();
@@ -246,10 +247,9 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
         // 4. read from the underlying connector
         Connector connector = connFactory.getConnector(init.getLeft());
-        ConnectorObject connectorObject = connector.getObject(
-                init.getRight().getObjectClass(),
+        ConnectorObject connectorObject = connector.getObject(init.getRight().getObjectClass(),
                 new Uid(connObjectKeyValue),
-                MappingUtils.buildOperationOptions(mapItems));
+                MappingManagerImpl.buildOperationOptions(mapItems));
         if (connectorObject == null) {
             throw new NotFoundException(
                     "Object " + connObjectKeyValue + " with class " + init.getRight().getObjectClass()

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 f72d6e9..5f2e632 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
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
 import java.lang.management.ManagementFactory;
 import java.lang.management.OperatingSystemMXBean;
 import java.lang.management.RuntimeMXBean;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.URI;
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.info.SystemInfo;
 import org.apache.syncope.common.lib.info.PlatformInfo;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.ImplementationLookup.Type;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 63e7984..7d30e0b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -52,8 +52,8 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 c544f68..200fd13 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,11 @@ 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.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -54,7 +54,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;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
 
 /**
  * Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
index f2fdb1f..1c71737 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.logic.init;
 
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
index eb0482f..e49c487 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
@@ -21,8 +21,8 @@ package org.apache.syncope.core.logic.init;
 import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 82134ed..2fa7b32 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
@@ -47,13 +47,13 @@ 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;
 import org.apache.syncope.core.logic.report.ReportJob;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+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.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
 import org.quartz.CronScheduleBuilder;
 import org.quartz.Job;
 import org.quartz.JobBuilder;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
index e83a768..8fadf47 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
@@ -26,7 +26,7 @@ import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.LoggerLevel;
 import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 13acaab..9f96ccc 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -30,8 +30,8 @@ import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
 import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
 import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
 import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.java.AuditManagerImpl;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -79,9 +79,10 @@ public class LoggerLoader implements SyncopeLoader {
                 ctx.getConfiguration().addAppender(appender);
             }
 
-            LoggerConfig logConf = new LoggerConfig(AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+            LoggerConfig logConf = new LoggerConfig(
+                    AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), null, false);
             logConf.addAppender(appender, Level.DEBUG, null);
-            ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
+            ctx.getConfiguration().addLogger(AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), logConf);
 
             AuthContextUtils.execWithAuthContext(entry.getKey(), new AuthContextUtils.Executable<Void>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
index 856fa13..10d1bf4 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
@@ -23,7 +23,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 7fea774..bd28aeb 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.logic.notification;
 
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob;
 import org.quartz.JobExecutionContext;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
index c09cca6..ea9b1da 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
@@ -25,12 +25,12 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
index 392c807..69caef9 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
@@ -26,9 +26,9 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.report.AuditReportletConf;
 import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.core.misc.AuditEntry;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.java.AuditEntry;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 413a665..1d890a6 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -34,7 +34,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
index 199c02d..37d69d7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
@@ -35,15 +35,14 @@ import org.apache.syncope.common.lib.report.ReconciliationReportletConf;
 import org.apache.syncope.common.lib.report.ReconciliationReportletConf.Feature;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 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.dao.search.AnyTypeCond;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -59,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 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.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -91,10 +91,7 @@ public class ReconciliationReportlet extends AbstractReportlet {
     private AnySearchDAO searchDAO;
 
     @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    private MappingUtils mappingUtils;
+    private MappingManager mappingManager;
 
     @Autowired
     private ConnectorFactory connFactory;
@@ -274,17 +271,16 @@ public class ReconciliationReportlet extends AbstractReportlet {
             AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
             for (final ExternalResource resource : anyUtils.getAllResources(any)) {
                 Provision provision = resource.getProvision(any.getType());
-                MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+                MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
                 if (provision != null && connObjectKeyItem != null) {
                     // 1. build connObjectKeyValue
-                    final String connObjectKeyValue = mappingUtils.getConnObjectKeyValue(any, provision);
+                    final String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, provision);
 
                     // 2. read from the underlying connector
                     Connector connector = connFactory.getConnector(resource);
-                    ConnectorObject connectorObject = connector.getObject(
-                            provision.getObjectClass(),
+                    ConnectorObject connectorObject = connector.getObject(provision.getObjectClass(),
                             new Uid(connObjectKeyValue),
-                            MappingUtils.buildOperationOptions(provision.getMapping().getItems().iterator()));
+                            MappingManagerImpl.buildOperationOptions(provision.getMapping().getItems().iterator()));
 
                     if (connectorObject == null) {
                         // 3. not found on resource?
@@ -295,7 +291,7 @@ public class ReconciliationReportlet extends AbstractReportlet {
                     } else {
                         // 4. found but misaligned?
                         Pair<String, Set<Attribute>> preparedAttrs =
-                                mappingUtils.prepareAttrs(any, null, false, null, provision);
+                                mappingManager.prepareAttrs(any, null, false, null, provision);
                         preparedAttrs.getRight().add(AttributeBuilder.build(
                                 Uid.NAME, preparedAttrs.getLeft()));
                         preparedAttrs.getRight().add(AttributeBuilder.build(

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index 5786cfb..19c2b86 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.logic.report;
 
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
index 1980858..e455778 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
@@ -33,8 +33,8 @@ import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.dao.ReportDAO;
 import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
index 37e896b..404d086 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic.report;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.report.StaticReportletConf;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.springframework.util.StringUtils;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index 1a447d8..724b8ac 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -36,8 +36,8 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 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.user.User;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/pom.xml
----------------------------------------------------------------------
diff --git a/core/misc/pom.xml b/core/misc/pom.xml
deleted file mode 100644
index 44e1df1..0000000
--- a/core/misc/pom.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.syncope</groupId>
-    <artifactId>syncope-core</artifactId>
-    <version>2.0.0-SNAPSHOT</version>
-  </parent>
-
-  <name>Apache Syncope Core Misc</name>
-  <description>Apache Syncope Core Misc</description>
-  <groupId>org.apache.syncope.core</groupId>
-  <artifactId>syncope-core-misc</artifactId>
-  <packaging>jar</packaging>
-  
-  <properties>
-    <rootpom.basedir>${basedir}/../..</rootpom.basedir>
-  </properties>
-
-  <dependencies>    
-    <dependency> 
-      <groupId>javax.servlet</groupId> 
-      <artifactId>javax.servlet-api</artifactId> 
-      <scope>provided</scope>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-jexl3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.module</groupId>
-      <artifactId>jackson-module-afterburner</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-tx</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.jasypt</groupId>
-      <artifactId>jasypt</artifactId>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-aop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-expression</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-web</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-provisioning-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>        
-    <dependency>
-      <groupId>org.apache.syncope.common</groupId>
-      <artifactId>syncope-common-rest-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <!-- TEST -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <version>${slf4j.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
deleted file mode 100644
index 3933bc3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
+++ /dev/null
@@ -1,77 +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.misc;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-
-public class AuditEntry extends AbstractBaseBean {
-
-    private static final long serialVersionUID = -2299082316063743582L;
-
-    private final String who;
-
-    private final AuditLoggerName logger;
-
-    private final Object before;
-
-    private final Object output;
-
-    private final Object[] input;
-
-    @JsonCreator
-    public AuditEntry(
-            @JsonProperty("who") final String who,
-            @JsonProperty("logger") final AuditLoggerName logger,
-            @JsonProperty("before") final Object before,
-            @JsonProperty("output") final Object output,
-            @JsonProperty("input") final Object[] input) {
-
-        super();
-        
-        this.who = who;
-        this.logger = logger;
-        this.before = before;
-        this.output = output;
-        this.input = input;
-    }
-
-    public String getWho() {
-        return who;
-    }
-
-    public AuditLoggerName getLogger() {
-        return logger;
-    }
-
-    public Object getBefore() {
-        return before;
-    }
-
-    public Object getOutput() {
-        return output;
-    }
-
-    public Object[] getInput() {
-        return input;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
deleted file mode 100644
index db243dc..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
+++ /dev/null
@@ -1,79 +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.misc;
-
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-import org.apache.syncope.common.lib.types.LoggerLevel;
-import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
-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;
-
-@Component
-public class AuditManager {
-
-    @Autowired
-    private LoggerDAO loggerDAO;
-
-    public static String getDomainAuditLoggerName(final String domain) {
-        return LoggerType.AUDIT.getPrefix() + "." + domain;
-    }
-
-    @Transactional(readOnly = true)
-    public void audit(
-            final AuditElements.EventCategoryType type,
-            final String category,
-            final String subcategory,
-            final String event,
-            final Result result,
-            final Object before,
-            final Object output,
-            final Object... input) {
-
-        Throwable throwable = null;
-        if (output instanceof Throwable) {
-            throwable = (Throwable) output;
-        }
-
-        AuditEntry auditEntry = new AuditEntry(
-                AuthContextUtils.getUsername(),
-                new AuditLoggerName(type, category, subcategory, event, result),
-                before,
-                throwable == null ? output : throwable.getMessage(),
-                input);
-
-        org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger =
-                loggerDAO.find(auditEntry.getLogger().toLoggerName());
-        if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
-            Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(AuthContextUtils.getDomain()));
-            if (throwable == null) {
-                logger.debug(POJOHelper.serialize(auditEntry));
-            } else {
-                logger.debug(POJOHelper.serialize(auditEntry), throwable);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java b/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
deleted file mode 100644
index 5a5d09a..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
+++ /dev/null
@@ -1,72 +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.misc;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.syncope.common.lib.types.AnyEntitlement;
-
-public final class EntitlementsHolder {
-
-    private static final Object MONITOR = new Object();
-
-    private static EntitlementsHolder INSTANCE;
-
-    public static EntitlementsHolder getInstance() {
-        synchronized (MONITOR) {
-            if (INSTANCE == null) {
-                INSTANCE = new EntitlementsHolder();
-            }
-        }
-        return INSTANCE;
-    }
-
-    private final Set<String> values = Collections.synchronizedSet(new HashSet<String>());
-
-    private EntitlementsHolder() {
-        // private constructor for singleton
-    }
-
-    public void init(final Collection<String> values) {
-        this.values.addAll(values);
-    }
-
-    public String getFor(final String anyTypeKey, final AnyEntitlement operation) {
-        return anyTypeKey + "_" + operation.name();
-    }
-
-    public void addFor(final String anyType) {
-        for (AnyEntitlement operation : AnyEntitlement.values()) {
-            this.values.add(getFor(anyType, operation));
-        }
-    }
-
-    public void removeFor(final String anyType) {
-        for (AnyEntitlement operation : AnyEntitlement.values()) {
-            this.values.remove(getFor(anyType, operation));
-        }
-    }
-
-    public Set<String> getValues() {
-        return Collections.unmodifiableSet(values);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
deleted file mode 100644
index d115ea9..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
+++ /dev/null
@@ -1,41 +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.misc.jexl;
-
-import org.apache.commons.jexl3.internal.introspection.Uberspect;
-import org.apache.commons.jexl3.introspection.JexlMethod;
-import org.apache.commons.jexl3.introspection.JexlPropertyGet;
-
-class ClassFreeUberspect extends Uberspect {
-
-    ClassFreeUberspect() {
-        super(null, null);
-    }
-
-    @Override
-    public JexlPropertyGet getPropertyGet(final Object obj, final Object identifier) {
-        return "class".equals(identifier) ? null : super.getPropertyGet(obj, identifier);
-    }
-
-    @Override
-    public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
-        return "getClass".equals(method) ? null : super.getMethod(obj, method, args);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java
deleted file mode 100644
index fe688f3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.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.misc.jexl;
-
-/**
- * A class loader that will throw {@link ClassNotFoundException} for every class name.
- */
-class EmptyClassLoader extends ClassLoader {
-
-    @Override
-    public Class<?> loadClass(final String name) throws ClassNotFoundException {
-        throw new ClassNotFoundException("This classloader won't attemp to load " + name);
-    }
-
-    @Override
-    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
-        throw new ClassNotFoundException("This classloader won't attemp to load " + name);
-    }
-
-}


[02/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
index 59113af..5e7190a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.provisioning.camel.data;
 
 import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
 import org.apache.syncope.core.provisioning.api.data.CamelRouteDataBinder;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
index 443e6aa..40afe61 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
index 189480b..f4ef0a5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
@@ -23,7 +23,7 @@ import java.util.Set;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
index 5a6fe52..f03c9f5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
index 2a8a318..584aaa5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
@@ -24,7 +24,7 @@ import org.apache.camel.Processor;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
index a33296d..e222643 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
index fbe34d1..2fb035c 100644
--- 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
@@ -29,7 +29,7 @@ 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.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
index 1c08e8a..785bd0f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
index 8603af2..30f9218 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
@@ -26,7 +26,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
index dd50c45..1c59157 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
index def3ca3..ff1f43a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
@@ -24,7 +24,7 @@ import org.apache.camel.Processor;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index 18aeac2..6cb270f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.patch.GroupPatch;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
index 05b2e75..5b16404 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
@@ -23,7 +23,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
index 51b8e83..0800bd3 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
@@ -25,7 +25,7 @@ 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.to.UserTO;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
index 328b091..0356afe 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
index 2438f17..a97a5b9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
index 324d54c..fdb42cb 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.patch.UserPatch;
 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.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
index 4877140..b8f09ab 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
@@ -27,7 +27,7 @@ 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.common.lib.types.StatusPatchType;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
index 6c1d3a3..7c4d6e0 100644
--- 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
@@ -25,7 +25,7 @@ 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.misc.spring.ApplicationContextProvider;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
index 57233a6..c9a5fbf 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
@@ -24,7 +24,7 @@ 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.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
index d334d75..e0360c6 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
@@ -25,15 +25,15 @@ under the License.
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">
 
-  <bean id="userRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="userRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${camel.directory}/userRoutes.xml"/>
     <property name="fallback" value="classpath:userRoutes.xml"/>
   </bean>
-  <bean id="groupRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="groupRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${camel.directory}/groupRoutes.xml"/>
     <property name="fallback" value="classpath:groupRoutes.xml"/>
   </bean>
-  <bean id="anyObjectRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="anyObjectRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${camel.directory}/anyObjectRoutes.xml"/>
     <property name="fallback" value="classpath:anyObjectRoutes.xml"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 985817b..78a7912 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -340,7 +340,7 @@ under the License.
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/misc/src/main/resources</directory>
+        <directory>${basedir}/../../core/spring/src/main/resources</directory>
         <includes>
           <include>security.properties</include>
         </includes>
@@ -784,9 +784,8 @@ under the License.
                     </excludes>
                   </resource>
                   <resource>
-                    <directory>${basedir}/../../core/misc/target/classes</directory>
+                    <directory>${basedir}/../../core/spring/target/classes</directory>
                     <excludes>
-                      <exclude>utilsContext.xml</exclude>
                       <exclude>securityContext.xml</exclude>
                     </excludes>
                   </resource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
index 2b67f37..d3039d0 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.fit.core.reference;
 
 import org.apache.syncope.common.lib.policy.AccountRuleConf;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
 import org.apache.syncope.core.persistence.api.dao.AccountRule;
 import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
 import org.apache.syncope.core.persistence.api.entity.user.User;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
index ea41274..2ca008b 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.fit.core.reference;
 
 import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
 import org.apache.syncope.core.persistence.api.dao.PasswordRule;
 import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
 import org.apache.syncope.core.persistence.api.entity.user.User;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 f6b5c2d..1603083 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.sync.DefaultReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.java.syncpull.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/28569df5/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
index dbe1bd1..19b172f 100644
--- 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
@@ -25,9 +25,9 @@ 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.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.java.sync.DefaultSyncActions;
+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;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
index 5cb8b10..5a1624a 100644
--- 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
@@ -20,7 +20,7 @@ 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.sync.SyncCorrelationRule;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 
 /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/coreContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/coreContext.xml b/fit/core-reference/src/main/resources/coreContext.xml
index ecdb57d..03f7fc9 100644
--- a/fit/core-reference/src/main/resources/coreContext.xml
+++ b/fit/core-reference/src/main/resources/coreContext.xml
@@ -54,6 +54,6 @@ under the License.
     </property>
   </bean>
 
-  <bean class="org.apache.syncope.core.misc.spring.ApplicationContextProvider"/>
+  <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml b/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
index e11e928..afd18ad 100644
--- a/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
+++ b/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
@@ -28,11 +28,11 @@ under the License.
                            http://www.springframework.org/schema/util
                            http://www.springframework.org/schema/util/spring-util.xsd">
   
-  <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="MasterContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
     <property name="fallback" value="classpath:domains/MasterContent.xml"/>
   </bean>
-  <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="MasterProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/Master.properties"/>
     <property name="fallback" value="classpath:domains/Master.properties"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml b/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
index 205553f..6d9d1bb 100644
--- a/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
+++ b/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
@@ -28,11 +28,11 @@ under the License.
                            http://www.springframework.org/schema/util
                            http://www.springframework.org/schema/util/spring-util.xsd">
   
-  <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="TwoContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
     <property name="fallback" value="classpath:domains/TwoContent.xml"/>
   </bean>
-  <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="TwoProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
     <property name="fallback" value="classpath:domains/Two.properties"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/webapp/cacheStats.jsp
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/cacheStats.jsp b/fit/core-reference/src/main/webapp/cacheStats.jsp
index 16063db..b599365 100644
--- a/fit/core-reference/src/main/webapp/cacheStats.jsp
+++ b/fit/core-reference/src/main/webapp/cacheStats.jsp
@@ -21,7 +21,7 @@ under the License.
 <%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
 <%@page import="org.springframework.beans.factory.support.DefaultListableBeanFactory"%>
 <%@page import="org.apache.syncope.common.lib.SyncopeConstants"%>
-<%@page import="org.apache.syncope.core.misc.spring.ApplicationContextProvider"%>
+<%@page import="org.apache.syncope.core.spring.ApplicationContextProvider"%>
 <%@page import="org.apache.commons.lang3.time.FastDateFormat"%>
 <%@page import="java.util.Date"%>
 <%@page import="org.apache.openjpa.datacache.CacheStatisticsImpl"%>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
index d32350c..43c9938 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
@@ -72,7 +72,7 @@ import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.service.AnyObjectService;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.fit.AbstractITCase;
 import org.junit.Assume;
 import org.junit.FixMethodOrder;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
index 3498b86..87bec8b 100644
--- 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
@@ -69,9 +69,9 @@ 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.misc.security.Encryptor;
-import org.apache.syncope.core.provisioning.java.sync.DBPasswordSyncActions;
-import org.apache.syncope.core.provisioning.java.sync.LDAPPasswordSyncActions;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
index 1cccb74..ff39d5f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -93,7 +93,7 @@ import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
 import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
 import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
 import org.apache.syncope.fit.core.reference.DoubleValueLogicActions;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/enduser-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 707e4f5..48dd75f 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -324,7 +324,7 @@ under the License.
                     </excludes>
                   </resource>
                   <resource>
-                    <directory>${basedir}/../../core/misc/target/classes</directory>
+                    <directory>${basedir}/../../core/spring/target/classes</directory>
                     <excludes>
                       <exclude>securityContext.xml</exclude>
                     </excludes>


[09/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
new file mode 100644
index 0000000..7c6c38a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -0,0 +1,241 @@
+/*
+ * 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.jexl;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.JexlException;
+import org.apache.commons.jexl3.JexlExpression;
+import org.apache.commons.jexl3.JxltEngine;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
+ */
+public final class JexlUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
+
+    private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
+
+    private static JexlEngine JEXL_ENGINE;
+
+    private static JexlEngine getEngine() {
+        synchronized (LOG) {
+            if (JEXL_ENGINE == null) {
+                JEXL_ENGINE = new JexlBuilder().
+                        uberspect(new ClassFreeUberspect()).
+                        loader(new EmptyClassLoader()).
+                        cache(512).
+                        silent(false).
+                        strict(false).
+                        create();
+            }
+        }
+
+        return JEXL_ENGINE;
+    }
+
+    public static JxltEngine newJxltEngine() {
+        return getEngine().createJxltEngine(false);
+    }
+
+    public static boolean isExpressionValid(final String expression) {
+        boolean result;
+        try {
+            getEngine().createExpression(expression);
+            result = true;
+        } catch (JexlException e) {
+            LOG.error("Invalid jexl expression: " + expression, e);
+            result = false;
+        }
+
+        return result;
+    }
+
+    public static String evaluate(final String expression, final JexlContext jexlContext) {
+        String result = StringUtils.EMPTY;
+
+        if (StringUtils.isNotBlank(expression) && jexlContext != null) {
+            try {
+                JexlExpression jexlExpression = getEngine().createExpression(expression);
+                Object evaluated = jexlExpression.evaluate(jexlContext);
+                if (evaluated != null) {
+                    result = evaluated.toString();
+                }
+            } catch (Exception e) {
+                LOG.error("Error while evaluating JEXL expression: " + expression, e);
+            }
+        } else {
+            LOG.debug("Expression not provided or invalid context");
+        }
+
+        return result;
+    }
+
+    public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
+        JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
+
+        try {
+            for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
+                Class<?> type = desc.getPropertyType();
+                String fieldName = desc.getName();
+
+                if ((!fieldName.startsWith("pc"))
+                        && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
+                        && (!Iterable.class.isAssignableFrom(type))
+                        && (!type.isArray())) {
+
+                    try {
+                        Object fieldValue;
+                        if (desc.getReadMethod() == null) {
+                            final Field field = object.getClass().getDeclaredField(fieldName);
+                            field.setAccessible(true);
+                            fieldValue = field.get(object);
+                        } else {
+                            fieldValue = desc.getReadMethod().invoke(object);
+                        }
+
+                        context.set(fieldName, fieldValue == null
+                                ? StringUtils.EMPTY
+                                : (type.equals(Date.class)
+                                ? FormatUtils.format((Date) fieldValue, false)
+                                : fieldValue));
+
+                        LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+                    } catch (Exception iae) {
+                        LOG.error("Reading '{}' value error", fieldName, iae);
+                    }
+                }
+            }
+        } catch (IntrospectionException ie) {
+            LOG.error("Reading class attributes error", ie);
+        }
+
+        if (object instanceof Any) {
+            Any<?> any = (Any<?>) object;
+            if (any.getRealm() != null) {
+                context.set("realm", any.getRealm().getName());
+            }
+        }
+
+        return context;
+    }
+
+    public static void addPlainAttrsToContext(
+            final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
+
+        for (PlainAttr<?> attr : attrs) {
+            if (attr.getSchema() != null) {
+                List<String> attrValues = attr.getValuesAsStrings();
+                String expressionValue = attrValues.isEmpty()
+                        ? StringUtils.EMPTY
+                        : attrValues.get(0);
+
+                LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
+
+                jexlContext.set(attr.getSchema().getKey(), expressionValue);
+            }
+        }
+    }
+
+    public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
+        Map<DerSchema, String> derAttrs =
+                ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
+
+        for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
+            jexlContext.set(entry.getKey().getKey(), entry.getValue());
+        }
+    }
+
+    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
+        JexlContext jexlContext = new MapContext();
+        addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+        addDerAttrsToContext(any, jexlContext);
+
+        return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
+    }
+
+    public static String evaluate(final String expression, final AnyTO anyTO) {
+        final JexlContext context = new MapContext();
+
+        addFieldsToContext(anyTO, context);
+
+        for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
+            List<String> values = plainAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
+
+            context.set(plainAttr.getSchema(), expressionValue);
+        }
+        for (AttrTO derAttr : anyTO.getDerAttrs()) {
+            List<String> values = derAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
+
+            context.set(derAttr.getSchema(), expressionValue);
+        }
+        for (AttrTO virAttr : anyTO.getVirAttrs()) {
+            List<String> values = virAttr.getValues();
+            String expressionValue = values.isEmpty()
+                    ? StringUtils.EMPTY
+                    : values.get(0);
+
+            LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
+
+            context.set(virAttr.getSchema(), expressionValue);
+        }
+
+        // Evaluate expression using the context prepared before
+        return evaluate(expression, context);
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private JexlUtils() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
index bd550b5..3b22728 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.java.job;
 
 import java.util.Date;
 import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
 import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.InterruptableJob;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
index ea6a525..aec8853 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -20,13 +20,13 @@ package org.apache.syncope.core.provisioning.java.job;
 
 import java.util.Date;
 import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.quartz.JobExecutionException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
index 4692e88..50067dc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.java.job;
 
 import org.apache.commons.lang3.ClassUtils;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 74dc39f..b119bd1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -54,8 +54,8 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 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.DerSchemaDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 7d7edc1..2c2e9ea 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -44,11 +44,10 @@ import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
@@ -59,6 +58,7 @@ 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.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
 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.notification.NotificationManager;
@@ -574,11 +574,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
         ConnectorObject obj = null;
         try {
-            obj = connector.getObject(
-                    new ObjectClass(task.getObjectClassName()),
+            obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
                     new Uid(connObjectKey),
-                    MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
-                            MappingUtils.getPropagationMappingItems(provision).iterator(),
+                    MappingManagerImpl.buildOperationOptions(IteratorUtils.chainedIterator(MappingManagerImpl.
+                            getPropagationMappingItems(provision).iterator(),
                             linkingMappingItems.iterator())));
 
             for (MappingItem item : linkingMappingItems) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
index 55c4a0b..635c015 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 9a7214c..6aa076e 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
@@ -30,7 +30,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 5ea6616..15ddb30 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -36,7 +36,7 @@ import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index f816228..5f66a2f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -43,9 +43,9 @@ 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.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 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.VirSchemaDAO;
@@ -58,6 +58,7 @@ 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.user.User;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -108,7 +109,7 @@ public class PropagationManagerImpl implements PropagationManager {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected MappingUtils mappingUtils;
+    protected MappingManager mappingManager;
 
     @Autowired
     protected AnyUtilsFactory anyUtilsFactory;
@@ -367,7 +368,7 @@ public class PropagationManagerImpl implements PropagationManager {
             Provision provision = resource == null ? null : resource.getProvision(any.getType());
             List<MappingItem> mappingItems = provision == null
                     ? Collections.<MappingItem>emptyList()
-                    : MappingUtils.getPropagationMappingItems(provision);
+                    : MappingManagerImpl.getPropagationMappingItems(provision);
 
             if (resource == null) {
                 LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -391,7 +392,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
                 Pair<String, Set<Attribute>> preparedAttrs =
-                        mappingUtils.prepareAttrs(any, password, changePwd, enable, provision);
+                        mappingManager.prepareAttrs(any, password, changePwd, enable, provision);
                 task.setConnObjectKey(preparedAttrs.getKey());
 
                 // Check if any of mandatory attributes (in the mapping) is missing or not received any value: 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
index 4e6b875..1c0aa9b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.java.propagation;
 
 import java.util.Collection;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
deleted file mode 100644
index d6f4c15..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
deleted file mode 100644
index f88982f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.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 MappingUtils mappingUtils;
-
-    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,
-                    MappingUtils.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 = mappingUtils.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());
-    }
-}


[03/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
new file mode 100644
index 0000000..ee55ea4
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
@@ -0,0 +1,334 @@
+/*
+ * 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.spring.security;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Generate random passwords according to given policies.
+ * When no minimum and / or maximum length are specified, default values are set.
+ *
+ * <strong>WARNING</strong>: This class only takes {@link DefaultPasswordRuleConf} into account.
+ */
+public class DefaultPasswordGenerator implements PasswordGenerator {
+
+    private static final char[] SPECIAL_CHARS = { '!', 'ÂŁ', '%', '&', '(', ')', '?', '#', '$' };
+
+    private static final int VERY_MIN_LENGTH = 0;
+
+    private static final int VERY_MAX_LENGTH = 64;
+
+    private static final int MIN_LENGTH_IF_ZERO = 6;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Override
+    public String generate(final User user) throws InvalidPasswordRuleConf {
+        List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+
+        for (Realm ancestor : realmDAO.findAncestors(user.getRealm())) {
+            if (ancestor.getPasswordPolicy() != null) {
+                ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
+            }
+        }
+
+        for (ExternalResource resource : userDAO.findAllResources(user)) {
+            if (resource.getPasswordPolicy() != null) {
+                ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
+            }
+        }
+
+        return generate(ruleConfs);
+    }
+
+    @Override
+    public String generate(final List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf {
+        List<DefaultPasswordRuleConf> defaultRuleConfs = new ArrayList<>();
+        for (PasswordRuleConf ruleConf : ruleConfs) {
+            if (ruleConf instanceof DefaultPasswordRuleConf) {
+                defaultRuleConfs.add((DefaultPasswordRuleConf) ruleConf);
+            }
+        }
+
+        DefaultPasswordRuleConf ruleConf = merge(defaultRuleConfs);
+        check(ruleConf);
+        return generate(ruleConf);
+    }
+
+    private DefaultPasswordRuleConf merge(final List<DefaultPasswordRuleConf> defaultRuleConfs) {
+        DefaultPasswordRuleConf result = new DefaultPasswordRuleConf();
+        result.setMinLength(VERY_MIN_LENGTH);
+        result.setMaxLength(VERY_MAX_LENGTH);
+
+        for (DefaultPasswordRuleConf ruleConf : defaultRuleConfs) {
+            if (ruleConf.getMinLength() > result.getMinLength()) {
+                result.setMinLength(ruleConf.getMinLength());
+            }
+
+            if ((ruleConf.getMaxLength() != 0) && ((ruleConf.getMaxLength() < result.getMaxLength()))) {
+                result.setMaxLength(ruleConf.getMaxLength());
+            }
+            result.getPrefixesNotPermitted().addAll(ruleConf.getPrefixesNotPermitted());
+            result.getSuffixesNotPermitted().addAll(ruleConf.getSuffixesNotPermitted());
+
+            if (!result.isNonAlphanumericRequired()) {
+                result.setNonAlphanumericRequired(ruleConf.isNonAlphanumericRequired());
+            }
+
+            if (!result.isAlphanumericRequired()) {
+                result.setAlphanumericRequired(ruleConf.isAlphanumericRequired());
+            }
+            if (!result.isDigitRequired()) {
+                result.setDigitRequired(ruleConf.isDigitRequired());
+            }
+
+            if (!result.isLowercaseRequired()) {
+                result.setLowercaseRequired(ruleConf.isLowercaseRequired());
+            }
+            if (!result.isUppercaseRequired()) {
+                result.setUppercaseRequired(ruleConf.isUppercaseRequired());
+            }
+            if (!result.isMustStartWithDigit()) {
+                result.setMustStartWithDigit(ruleConf.isMustStartWithDigit());
+            }
+            if (!result.isMustntStartWithDigit()) {
+                result.setMustntStartWithDigit(ruleConf.isMustntStartWithDigit());
+            }
+            if (!result.isMustEndWithDigit()) {
+                result.setMustEndWithDigit(ruleConf.isMustEndWithDigit());
+            }
+            if (result.isMustntEndWithDigit()) {
+                result.setMustntEndWithDigit(ruleConf.isMustntEndWithDigit());
+            }
+            if (!result.isMustStartWithAlpha()) {
+                result.setMustStartWithAlpha(ruleConf.isMustStartWithAlpha());
+            }
+            if (!result.isMustntStartWithAlpha()) {
+                result.setMustntStartWithAlpha(ruleConf.isMustntStartWithAlpha());
+            }
+            if (!result.isMustStartWithNonAlpha()) {
+                result.setMustStartWithNonAlpha(ruleConf.isMustStartWithNonAlpha());
+            }
+            if (!result.isMustntStartWithNonAlpha()) {
+                result.setMustntStartWithNonAlpha(ruleConf.isMustntStartWithNonAlpha());
+            }
+            if (!result.isMustEndWithNonAlpha()) {
+                result.setMustEndWithNonAlpha(ruleConf.isMustEndWithNonAlpha());
+            }
+            if (!result.isMustntEndWithNonAlpha()) {
+                result.setMustntEndWithNonAlpha(ruleConf.isMustntEndWithNonAlpha());
+            }
+            if (!result.isMustEndWithAlpha()) {
+                result.setMustEndWithAlpha(ruleConf.isMustEndWithAlpha());
+            }
+            if (!result.isMustntEndWithAlpha()) {
+                result.setMustntEndWithAlpha(ruleConf.isMustntEndWithAlpha());
+            }
+            if (!result.isUsernameAllowed()) {
+                result.setUsernameAllowed(ruleConf.isUsernameAllowed());
+            }
+        }
+
+        if (result.getMinLength() == 0) {
+            result.setMinLength(
+                    result.getMaxLength() < MIN_LENGTH_IF_ZERO ? result.getMaxLength() : MIN_LENGTH_IF_ZERO);
+        }
+
+        return result;
+    }
+
+    private void check(final DefaultPasswordRuleConf defaultPasswordRuleConf)
+            throws InvalidPasswordRuleConf {
+
+        if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustntEndWithAlpha()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustEndWithAlpha and mustntEndWithAlpha are both true");
+        }
+        if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustEndWithDigit()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustEndWithAlpha and mustEndWithDigit are both true");
+        }
+        if (defaultPasswordRuleConf.isMustEndWithDigit() && defaultPasswordRuleConf.isMustntEndWithDigit()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustEndWithDigit and mustntEndWithDigit are both true");
+        }
+        if (defaultPasswordRuleConf.isMustEndWithNonAlpha() && defaultPasswordRuleConf.isMustntEndWithNonAlpha()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustEndWithNonAlpha and mustntEndWithNonAlpha are both true");
+        }
+        if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustntStartWithAlpha()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustStartWithAlpha and mustntStartWithAlpha are both true");
+        }
+        if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustStartWithDigit()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustStartWithAlpha and mustStartWithDigit are both true");
+        }
+        if (defaultPasswordRuleConf.isMustStartWithDigit() && defaultPasswordRuleConf.isMustntStartWithDigit()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustStartWithDigit and mustntStartWithDigit are both true");
+        }
+        if (defaultPasswordRuleConf.isMustStartWithNonAlpha() && defaultPasswordRuleConf.isMustntStartWithNonAlpha()) {
+            throw new InvalidPasswordRuleConf(
+                    "mustStartWithNonAlpha and mustntStartWithNonAlpha are both true");
+        }
+        if (defaultPasswordRuleConf.getMinLength() > defaultPasswordRuleConf.getMaxLength()) {
+            throw new InvalidPasswordRuleConf(
+                    "Minimun length (" + defaultPasswordRuleConf.getMinLength() + ")"
+                    + "is greater than maximum length (" + defaultPasswordRuleConf.getMaxLength() + ")");
+        }
+    }
+
+    private String generate(final DefaultPasswordRuleConf ruleConf) {
+        String[] generatedPassword = new String[ruleConf.getMinLength()];
+
+        for (int i = 0; i < generatedPassword.length; i++) {
+            generatedPassword[i] = StringUtils.EMPTY;
+        }
+
+        checkStartChar(generatedPassword, ruleConf);
+
+        checkEndChar(generatedPassword, ruleConf);
+
+        checkRequired(generatedPassword, ruleConf);
+
+        for (int firstEmptyChar = firstEmptyChar(generatedPassword);
+                firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
+
+            generatedPassword[firstEmptyChar] = SecureRandomUtils.generateRandomLetter();
+        }
+
+        checkPrefixAndSuffix(generatedPassword, ruleConf);
+
+        return StringUtils.join(generatedPassword);
+    }
+
+    private void checkStartChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+        if (ruleConf.isMustStartWithAlpha()) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
+        if (ruleConf.isMustStartWithNonAlpha() || ruleConf.isMustStartWithDigit()) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
+        }
+        if (ruleConf.isMustntStartWithAlpha()) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
+        }
+        if (ruleConf.isMustntStartWithDigit()) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
+        if (ruleConf.isMustntStartWithNonAlpha()) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[0])) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
+    }
+
+    private void checkEndChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+        if (ruleConf.isMustEndWithAlpha()) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
+        if (ruleConf.isMustEndWithNonAlpha() || ruleConf.isMustEndWithDigit()) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
+        }
+
+        if (ruleConf.isMustntEndWithAlpha()) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
+        }
+        if (ruleConf.isMustntEndWithDigit()) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
+        if (ruleConf.isMustntEndWithNonAlpha()) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[ruleConf.getMinLength() - 1])) {
+            generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
+    }
+
+    private int firstEmptyChar(final String[] generatedPStrings) {
+        int index = 0;
+        while (!generatedPStrings[index].isEmpty()) {
+            index++;
+        }
+        return index;
+    }
+
+    private void checkRequired(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+        if (ruleConf.isDigitRequired()
+                && !PolicyPattern.DIGIT.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+            generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtils.generateRandomNumber();
+        }
+
+        if (ruleConf.isUppercaseRequired()
+                && !PolicyPattern.ALPHA_UPPERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+            generatedPassword[firstEmptyChar(generatedPassword)] =
+                    SecureRandomUtils.generateRandomLetter().toUpperCase();
+        }
+
+        if (ruleConf.isLowercaseRequired()
+                && !PolicyPattern.ALPHA_LOWERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+            generatedPassword[firstEmptyChar(generatedPassword)] =
+                    SecureRandomUtils.generateRandomLetter().toLowerCase();
+        }
+
+        if (ruleConf.isNonAlphanumericRequired()
+                && !PolicyPattern.NON_ALPHANUMERIC.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+            generatedPassword[firstEmptyChar(generatedPassword)] =
+                    SecureRandomUtils.generateRandomSpecialCharacter(SPECIAL_CHARS);
+        }
+    }
+
+    private void checkPrefixAndSuffix(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+        for (String prefix : ruleConf.getPrefixesNotPermitted()) {
+            if (StringUtils.join(generatedPassword).startsWith(prefix)) {
+                checkStartChar(generatedPassword, ruleConf);
+            }
+        }
+
+        for (String suffix : ruleConf.getSuffixesNotPermitted()) {
+            if (StringUtils.join(generatedPassword).endsWith(suffix)) {
+                checkEndChar(generatedPassword, ruleConf);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
new file mode 100644
index 0000000..d99c96c
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.spring.security;
+
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public class DelegatedAdministrationException extends RuntimeException {
+
+    private static final long serialVersionUID = 7540587364235915081L;
+
+    public DelegatedAdministrationException(final AnyTypeKind type, final Long key) {
+        super("Missing entitlement or realm administration for "
+                + (key == null
+                        ? "new " + type
+                        : type + " " + key));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
new file mode 100644
index 0000000..a1e8a9e
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
@@ -0,0 +1,256 @@
+/*
+ * 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.spring.security;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.jasypt.commons.CommonUtils;
+import org.jasypt.digest.StandardStringDigester;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.crypto.bcrypt.BCrypt;
+import org.springframework.security.crypto.codec.Base64;
+
+public final class Encryptor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Encryptor.class);
+
+    private static final Map<String, Encryptor> INSTANCES = new ConcurrentHashMap<>();
+
+    private static final String DEFAULT_SECRET_KEY = "1abcdefghilmnopqrstuvz2!";
+
+    /**
+     * Default value for salted {@link StandardStringDigester#setIterations(int)}.
+     */
+    private static final int DEFAULT_SALT_ITERATIONS = 1;
+
+    /**
+     * Default value for {@link StandardStringDigester#setSaltSizeBytes(int)}.
+     */
+    private static final int DEFAULT_SALT_SIZE_BYTES = 8;
+
+    /**
+     * Default value for {@link StandardStringDigester#setInvertPositionOfPlainSaltInEncryptionResults(boolean)}.
+     */
+    private static final boolean DEFAULT_IPOPSIER = true;
+
+    /**
+     * Default value for salted {@link StandardStringDigester#setInvertPositionOfSaltInMessageBeforeDigesting(boolean)}.
+     */
+    private static final boolean DEFAULT_IPOSIMBD = true;
+
+    /**
+     * Default value for salted {@link StandardStringDigester#setUseLenientSaltSizeCheck(boolean)}.
+     */
+    private static final boolean DEFAULT_ULSSC = true;
+
+    private static String SECRET_KEY;
+
+    private static Integer SALT_ITERATIONS;
+
+    private static Integer SALT_SIZE_BYTES;
+
+    private static Boolean IPOPSIER;
+
+    private static Boolean IPOSIMBD;
+
+    private static Boolean ULSSC;
+
+    static {
+        InputStream propStream = null;
+        try {
+            propStream = Encryptor.class.getResourceAsStream("/security.properties");
+            Properties props = new Properties();
+            props.load(propStream);
+
+            SECRET_KEY = props.getProperty("secretKey");
+            SALT_ITERATIONS = Integer.valueOf(props.getProperty("digester.saltIterations"));
+            SALT_SIZE_BYTES = Integer.valueOf(props.getProperty("digester.saltSizeBytes"));
+            IPOPSIER = Boolean.valueOf(props.getProperty("digester.invertPositionOfPlainSaltInEncryptionResults"));
+            IPOSIMBD = Boolean.valueOf(props.getProperty("digester.invertPositionOfSaltInMessageBeforeDigesting"));
+            ULSSC = Boolean.valueOf(props.getProperty("digester.useLenientSaltSizeCheck"));
+        } catch (Exception e) {
+            LOG.error("Could not read security parameters", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+
+        if (SECRET_KEY == null) {
+            SECRET_KEY = DEFAULT_SECRET_KEY;
+            LOG.debug("secretKey not found, reverting to default");
+        }
+        if (SALT_ITERATIONS == null) {
+            SALT_ITERATIONS = DEFAULT_SALT_ITERATIONS;
+            LOG.debug("digester.saltIterations not found, reverting to default");
+        }
+        if (SALT_SIZE_BYTES == null) {
+            SALT_SIZE_BYTES = DEFAULT_SALT_SIZE_BYTES;
+            LOG.debug("digester.saltSizeBytes not found, reverting to default");
+        }
+        if (IPOPSIER == null) {
+            IPOPSIER = DEFAULT_IPOPSIER;
+            LOG.debug("digester.invertPositionOfPlainSaltInEncryptionResults not found, reverting to default");
+        }
+        if (IPOSIMBD == null) {
+            IPOSIMBD = DEFAULT_IPOSIMBD;
+            LOG.debug("digester.invertPositionOfSaltInMessageBeforeDigesting not found, reverting to default");
+        }
+        if (ULSSC == null) {
+            ULSSC = DEFAULT_ULSSC;
+            LOG.debug("digester.useLenientSaltSizeCheck not found, reverting to default");
+        }
+    }
+
+    public static Encryptor getInstance() {
+        return getInstance(SECRET_KEY);
+    }
+
+    public static Encryptor getInstance(final String secretKey) {
+        String actualKey = StringUtils.isBlank(secretKey) ? DEFAULT_SECRET_KEY : secretKey;
+
+        Encryptor instance = INSTANCES.get(actualKey);
+        if (instance == null) {
+            instance = new Encryptor(actualKey);
+            INSTANCES.put(actualKey, instance);
+        }
+
+        return instance;
+    }
+
+    private SecretKeySpec keySpec;
+
+    private Encryptor(final String secretKey) {
+        String actualKey = secretKey;
+        if (actualKey.length() < 16) {
+            StringBuilder actualKeyPadding = new StringBuilder(actualKey);
+            for (int i = 0; i < 16 - actualKey.length(); i++) {
+                actualKeyPadding.append('0');
+            }
+            actualKey = actualKeyPadding.toString();
+            LOG.debug("actualKey too short, adding some random characters");
+        }
+
+        try {
+            keySpec = new SecretKeySpec(ArrayUtils.subarray(
+                    actualKey.getBytes(SyncopeConstants.DEFAULT_CHARSET), 0, 16),
+                    CipherAlgorithm.AES.getAlgorithm());
+        } catch (Exception e) {
+            LOG.error("Error during key specification", e);
+        }
+    }
+
+    public String encode(final String value, final CipherAlgorithm cipherAlgorithm)
+            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            IllegalBlockSizeException, BadPaddingException {
+
+        String encodedValue = null;
+
+        if (value != null) {
+            if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
+                final byte[] cleartext = value.getBytes(SyncopeConstants.DEFAULT_CHARSET);
+
+                final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
+                cipher.init(Cipher.ENCRYPT_MODE, keySpec);
+
+                encodedValue = new String(Base64.encode(cipher.doFinal(cleartext)));
+            } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
+                encodedValue = BCrypt.hashpw(value, BCrypt.gensalt());
+            } else {
+                encodedValue = getDigester(cipherAlgorithm).digest(value);
+            }
+        }
+
+        return encodedValue;
+    }
+
+    public boolean verify(final String value, final CipherAlgorithm cipherAlgorithm, final String encodedValue) {
+        boolean res = false;
+
+        try {
+            if (value != null) {
+                if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
+                    res = encode(value, cipherAlgorithm).equals(encodedValue);
+                } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
+                    res = BCrypt.checkpw(value, encodedValue);
+                } else {
+                    res = getDigester(cipherAlgorithm).matches(value, encodedValue);
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Could not verify encoded value", e);
+        }
+
+        return res;
+    }
+
+    public String decode(final String encodedValue, final CipherAlgorithm cipherAlgorithm)
+            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            IllegalBlockSizeException, BadPaddingException {
+
+        String value = null;
+
+        if (encodedValue != null && cipherAlgorithm == CipherAlgorithm.AES) {
+            final byte[] encoded = encodedValue.getBytes(SyncopeConstants.DEFAULT_CHARSET);
+
+            final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
+            cipher.init(Cipher.DECRYPT_MODE, keySpec);
+
+            value = new String(cipher.doFinal(Base64.decode(encoded)), SyncopeConstants.DEFAULT_CHARSET);
+        }
+
+        return value;
+    }
+
+    private StandardStringDigester getDigester(final CipherAlgorithm cipherAlgorithm) {
+        StandardStringDigester digester = new StandardStringDigester();
+
+        if (cipherAlgorithm.getAlgorithm().startsWith("S-")) {
+            // Salted ...
+            digester.setAlgorithm(cipherAlgorithm.getAlgorithm().replaceFirst("S\\-", ""));
+            digester.setIterations(SALT_ITERATIONS);
+            digester.setSaltSizeBytes(SALT_SIZE_BYTES);
+            digester.setInvertPositionOfPlainSaltInEncryptionResults(IPOPSIER);
+            digester.setInvertPositionOfSaltInMessageBeforeDigesting(IPOSIMBD);
+            digester.setUseLenientSaltSizeCheck(ULSSC);
+        } else {
+            // Not salted ...
+            digester.setAlgorithm(cipherAlgorithm.getAlgorithm());
+            digester.setIterations(1);
+            digester.setSaltSizeBytes(0);
+        }
+
+        digester.setStringOutputType(CommonUtils.STRING_OUTPUT_TYPE_HEXADECIMAL);
+        return digester;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
new file mode 100644
index 0000000..f9939dd
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.spring.security;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
+
+public class MustChangePasswordFilter implements Filter {
+
+    private static final String[] ALLOWED = new String[] {
+        "/users/self", "/users/self/changePassword"
+    };
+
+    @Override
+    public void init(final FilterConfig filterConfig) throws ServletException {
+        // not used
+    }
+
+    @Override
+    public void destroy() {
+        // not used
+    }
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+            throws IOException, ServletException {
+
+        if (request instanceof SecurityContextHolderAwareRequestWrapper) {
+            boolean isMustChangePassword = IterableUtils.matchesAny(
+                    SecurityContextHolder.getContext().getAuthentication().getAuthorities(),
+                    new Predicate<GrantedAuthority>() {
+
+                @Override
+                public boolean evaluate(final GrantedAuthority authority) {
+                    return StandardEntitlement.MUST_CHANGE_PASSWORD.equals(authority.getAuthority());
+                }
+            });
+
+            SecurityContextHolderAwareRequestWrapper wrapper =
+                    SecurityContextHolderAwareRequestWrapper.class.cast(request);
+            if (isMustChangePassword && "GET".equalsIgnoreCase(wrapper.getMethod())
+                    && !ArrayUtils.contains(ALLOWED, wrapper.getPathInfo())) {
+
+                throw new AccessDeniedException("Please change your password first");
+            }
+        }
+
+        chain.doFilter(request, response);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
new file mode 100644
index 0000000..ad6b56b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
@@ -0,0 +1,32 @@
+/*
+ * 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.spring.security;
+
+import java.util.List;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+
+public interface PasswordGenerator {
+
+    String generate(User user) throws InvalidPasswordRuleConf;
+
+    String generate(List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
new file mode 100644
index 0000000..04aad69
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
@@ -0,0 +1,48 @@
+/*
+ * 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.spring.security;
+
+import java.security.SecureRandom;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+public final class SecureRandomUtils {
+
+    private static final SecureRandom RANDOM = new SecureRandom();
+
+    public static String generateRandomPassword(final int tokenLength) {
+        return RandomStringUtils.random(tokenLength, 0, 0, true, false, null, RANDOM);
+    }
+
+    public static String generateRandomLetter() {
+        return RandomStringUtils.random(1, 0, 0, true, false, null, RANDOM);
+    }
+
+    public static String generateRandomNumber() {
+        return RandomStringUtils.random(1, 0, 0, false, true, null, RANDOM);
+    }
+
+    public static String generateRandomSpecialCharacter(final char[] characters) {
+        return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
+    }
+
+    private SecureRandomUtils() {
+        // private constructor for static utility class
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java
new file mode 100644
index 0000000..888cae9
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java
@@ -0,0 +1,43 @@
+/*
+ * 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.spring.security;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.access.AccessDeniedHandlerImpl;
+
+/**
+ * Render Spring's {@link AccessDeniedException} as other Syncope errors.
+ */
+public class SyncopeAccessDeniedHandler extends AccessDeniedHandlerImpl {
+
+    @Override
+    public void handle(final HttpServletRequest request, final HttpServletResponse response,
+            final AccessDeniedException accessDeniedException) throws IOException, ServletException {
+
+        response.addHeader(RESTHeaders.ERROR_INFO, accessDeniedException.getMessage());
+
+        super.handle(request, response, accessDeniedException);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
new file mode 100644
index 0000000..c427c48
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
@@ -0,0 +1,86 @@
+/*
+ * 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.spring.security;
+
+import java.io.Serializable;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+public class SyncopeAuthenticationDetails implements Serializable {
+
+    private static final long serialVersionUID = -5899959397393502897L;
+
+    private final String remoteAddress;
+
+    private final String sessionId;
+
+    private String domain;
+
+    public SyncopeAuthenticationDetails(final HttpServletRequest request) {
+        this.remoteAddress = request.getRemoteAddr();
+
+        HttpSession session = request.getSession(false);
+        this.sessionId = session == null ? null : session.getId();
+
+        this.domain = request.getHeader(RESTHeaders.DOMAIN);
+    }
+
+    public SyncopeAuthenticationDetails(final String domain) {
+        this.remoteAddress = null;
+        this.sessionId = null;
+        this.domain = domain;
+    }
+
+    public String getRemoteAddress() {
+        return remoteAddress;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(final String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
new file mode 100644
index 0000000..0b2b27c
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
@@ -0,0 +1,32 @@
+/*
+ * 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.spring.security;
+
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.security.authentication.AuthenticationDetailsSource;
+
+public class SyncopeAuthenticationDetailsSource
+        implements AuthenticationDetailsSource<HttpServletRequest, SyncopeAuthenticationDetails> {
+
+    @Override
+    public SyncopeAuthenticationDetails buildDetails(final HttpServletRequest context) {
+        return new SyncopeAuthenticationDetails(context);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java
new file mode 100644
index 0000000..7f9ad7b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java
@@ -0,0 +1,43 @@
+/*
+ * 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.spring.security;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
+
+/**
+ * Render Spring's {@link AuthenticationException} as other Syncope errors.
+ */
+public class SyncopeAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
+
+    @Override
+    public void commence(final HttpServletRequest request, final HttpServletResponse response,
+            final AuthenticationException authException) throws IOException, ServletException {
+
+        response.addHeader(RESTHeaders.ERROR_INFO, authException.getMessage());
+
+        super.commence(request, response, authException);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
new file mode 100644
index 0000000..078ebc4
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
@@ -0,0 +1,210 @@
+/*
+ * 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.spring.security;
+
+import javax.annotation.Resource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.spring.security.AuthContextUtils.Executable;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+@Configurable
+public class SyncopeAuthenticationProvider implements AuthenticationProvider {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
+
+    @Autowired
+    protected AuthDataAccessor dataAccessor;
+
+    @Autowired
+    protected UserProvisioningManager provisioningManager;
+
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
+    @Resource(name = "anonymousUser")
+    protected String anonymousUser;
+
+    protected String adminPassword;
+
+    protected String adminPasswordAlgorithm;
+
+    protected String anonymousKey;
+
+    protected UserDetailsService userDetailsService;
+
+    protected final Encryptor encryptor = Encryptor.getInstance();
+
+    /**
+     * @param adminPassword the adminPassword to set
+     */
+    public void setAdminPassword(final String adminPassword) {
+        this.adminPassword = adminPassword;
+    }
+
+    /**
+     * @param adminPasswordAlgorithm the adminPasswordAlgorithm to set
+     */
+    public void setAdminPasswordAlgorithm(final String adminPasswordAlgorithm) {
+        this.adminPasswordAlgorithm = adminPasswordAlgorithm;
+    }
+
+    /**
+     * @param anonymousKey the anonymousKey to set
+     */
+    public void setAnonymousKey(final String anonymousKey) {
+        this.anonymousKey = anonymousKey;
+    }
+
+    public void setUserDetailsService(final UserDetailsService syncopeUserDetailsService) {
+        this.userDetailsService = syncopeUserDetailsService;
+    }
+
+    @Override
+    public Authentication authenticate(final Authentication authentication) {
+        String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
+        if (StringUtils.isBlank(domainKey)) {
+            domainKey = SyncopeConstants.MASTER_DOMAIN;
+        }
+        SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
+
+        Boolean authenticated;
+        if (anonymousUser.equals(authentication.getName())) {
+            authenticated = authentication.getCredentials().toString().equals(anonymousKey);
+        } else if (adminUser.equals(authentication.getName())) {
+            if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
+                authenticated = encryptor.verify(
+                        authentication.getCredentials().toString(),
+                        CipherAlgorithm.valueOf(adminPasswordAlgorithm),
+                        adminPassword);
+            } else {
+                final String domainToFind = domainKey;
+                authenticated = AuthContextUtils.execWithAuthContext(
+                        SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
+
+                            @Override
+                            public Boolean exec() {
+                                Domain domain = dataAccessor.findDomain(domainToFind);
+
+                                return encryptor.verify(
+                                        authentication.getCredentials().toString(),
+                                        domain.getAdminCipherAlgorithm(),
+                                        domain.getAdminPwd());
+                            }
+                        });
+            }
+        } else {
+            final Pair<Long, Boolean> authResult =
+                    AuthContextUtils.execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
+
+                        @Override
+                        public Pair<Long, Boolean> exec() {
+                            return dataAccessor.authenticate(authentication);
+                        }
+                    });
+            authenticated = authResult.getValue();
+            if (authenticated != null && !authenticated) {
+                AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
+
+                    @Override
+                    public Void exec() {
+                        provisioningManager.internalSuspend(authResult.getKey());
+                        return null;
+                    }
+                });
+            }
+        }
+
+        final boolean isAuthenticated = authenticated != null && authenticated;
+        UsernamePasswordAuthenticationToken token;
+        if (isAuthenticated) {
+            token = AuthContextUtils.execWithAuthContext(
+                    domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
+
+                        @Override
+                        public UsernamePasswordAuthenticationToken exec() {
+                            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
+                                    authentication.getPrincipal(),
+                                    null,
+                                    userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
+                                    getAuthorities());
+                            token.setDetails(authentication.getDetails());
+
+                            dataAccessor.audit(
+                                    AuditElements.EventCategoryType.REST,
+                                    AuditElements.AUTHENTICATION_CATEGORY,
+                                    null,
+                                    AuditElements.LOGIN_EVENT,
+                                    Result.SUCCESS,
+                                    null,
+                                    isAuthenticated,
+                                    authentication,
+                                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
+                            return token;
+                        }
+                    });
+
+            LOG.debug("User {} successfully authenticated, with entitlements {}",
+                    authentication.getPrincipal(), token.getAuthorities());
+        } else {
+            AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
+
+                @Override
+                public Void exec() {
+                    dataAccessor.audit(
+                            AuditElements.EventCategoryType.REST,
+                            AuditElements.AUTHENTICATION_CATEGORY,
+                            null,
+                            AuditElements.LOGIN_EVENT,
+                            Result.FAILURE,
+                            null,
+                            isAuthenticated,
+                            authentication,
+                            "User " + authentication.getPrincipal() + " not authenticated");
+                    return null;
+                }
+            });
+
+            LOG.debug("User {} not authenticated", authentication.getPrincipal());
+
+            throw new BadCredentialsException("User " + authentication.getPrincipal() + " not authenticated");
+        }
+
+        return token;
+    }
+
+    @Override
+    public boolean supports(final Class<? extends Object> type) {
+        return type.equals(UsernamePasswordAuthenticationToken.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
new file mode 100644
index 0000000..e23902b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
@@ -0,0 +1,90 @@
+/*
+ * 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.spring.security;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+public class SyncopeGrantedAuthority implements GrantedAuthority {
+
+    private static final long serialVersionUID = -5647624636011919735L;
+
+    private final String entitlement;
+
+    private final Set<String> realms = SetUtils.orderedSet(new HashSet<String>());
+
+    public SyncopeGrantedAuthority(final String entitlement) {
+        this.entitlement = entitlement;
+    }
+
+    public SyncopeGrantedAuthority(final String entitlement, final String realm) {
+        this.entitlement = entitlement;
+        this.realms.add(realm);
+    }
+
+    public boolean addRealm(final String newRealm) {
+        return RealmUtils.normalizingAddTo(realms, newRealm);
+    }
+
+    public void addRealms(final Collection<String> newRealms) {
+        IterableUtils.forEach(newRealms, new Closure<String>() {
+
+            @Override
+            public void execute(final String newRealm) {
+                addRealm(newRealm);
+            }
+        });
+    }
+
+    public Set<String> getRealms() {
+        return Collections.unmodifiableSet(realms);
+    }
+
+    @Override
+    public String getAuthority() {
+        return entitlement;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
new file mode 100644
index 0000000..544fc99
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.spring.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+@Configurable
+public class SyncopeUserDetailsService implements UserDetailsService {
+
+    @Autowired
+    protected AuthDataAccessor dataAccessor;
+
+    @Override
+    public UserDetails loadUserByUsername(final String username) {
+        return new User(username, "<PASSWORD_PLACEHOLDER>", dataAccessor.load(username));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/resources/security.properties
----------------------------------------------------------------------
diff --git a/core/spring/src/main/resources/security.properties b/core/spring/src/main/resources/security.properties
new file mode 100644
index 0000000..6bb5210
--- /dev/null
+++ b/core/spring/src/main/resources/security.properties
@@ -0,0 +1,32 @@
+# 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.
+adminUser=admin
+adminPassword=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
+adminPasswordAlgorithm=SHA1
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+secretKey=${secretKey}
+# default for LDAP / RFC2307 SSHA
+digester.saltIterations=1
+digester.saltSizeBytes=8
+digester.invertPositionOfPlainSaltInEncryptionResults=true
+digester.invertPositionOfSaltInMessageBeforeDigesting=true
+digester.useLenientSaltSizeCheck=true
+
+passwordGenerator=org.apache.syncope.core.spring.security.DefaultPasswordGenerator

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/spring/src/main/resources/securityContext.xml b/core/spring/src/main/resources/securityContext.xml
new file mode 100644
index 0000000..0e2072f
--- /dev/null
+++ b/core/spring/src/main/resources/securityContext.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:security="http://www.springframework.org/schema/security"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://www.springframework.org/schema/security
+                           http://www.springframework.org/schema/security/spring-security.xsd">
+
+  <bean id="adminUser" class="java.lang.String">
+    <constructor-arg value="${adminUser}"/>
+  </bean>
+  <bean id="anonymousUser" class="java.lang.String">
+    <constructor-arg value="${anonymousUser}"/>
+  </bean>
+  
+  <bean class="${passwordGenerator}"/>
+  <bean class="org.apache.syncope.core.spring.DefaultRolesPrefixPostProcessor"/>
+  
+  <security:global-method-security pre-post-annotations="enabled"/>
+  
+  <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
+    <security:filter-chain-map request-matcher="ant">
+      <security:filter-chain pattern="/**" filters="securityContextPersistenceFilter"/>
+    </security:filter-chain-map>
+  </bean>
+  
+  <bean id="securityContextRepository" class='org.springframework.security.web.context.NullSecurityContextRepository'/>
+
+  <bean id="securityContextPersistenceFilter"
+        class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
+    <constructor-arg ref="securityContextRepository"/>
+  </bean>
+
+  <bean id="syncopeAuthenticationDetailsSource"
+        class="org.apache.syncope.core.spring.security.SyncopeAuthenticationDetailsSource"/>
+
+  <bean id="mustChangePasswordFilter" class="org.apache.syncope.core.spring.security.MustChangePasswordFilter"/>
+      
+  <bean id="syncopeAuthenticationEntryPoint" 
+        class="org.apache.syncope.core.spring.security.SyncopeAuthenticationEntryPoint">
+    <property name="realmName" value="Apache Syncope authentication"/>
+  </bean>
+
+  <bean id="syncopeAccessDeniedHandler" class="org.apache.syncope.core.spring.security.SyncopeAccessDeniedHandler"/>
+  
+  <security:http security-context-repository-ref="securityContextRepository"
+                 use-expressions="false" disable-url-rewriting="false">
+
+    <security:http-basic entry-point-ref="syncopeAuthenticationEntryPoint"
+                         authentication-details-source-ref="syncopeAuthenticationDetailsSource"/>
+    <security:anonymous username="${anonymousUser}"/>
+    <security:intercept-url pattern="/**"/>
+    
+    <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="mustChangePasswordFilter"/>
+    
+    <security:access-denied-handler ref="syncopeAccessDeniedHandler"/>
+    
+    <security:headers disabled="true"/>
+    <security:csrf disabled="true"/>
+  </security:http>
+
+  <bean class="org.apache.syncope.core.spring.security.AuthDataAccessor"/>
+
+  <bean id="syncopeUserDetailsService" class="org.apache.syncope.core.spring.security.SyncopeUserDetailsService"/>
+
+  <bean id="syncopeAuthenticationProvider"
+        class="org.apache.syncope.core.spring.security.SyncopeAuthenticationProvider">
+    <property name="adminPassword" value="${adminPassword}"/>
+    <property name="adminPasswordAlgorithm" value="${adminPasswordAlgorithm}"/>
+    <property name="anonymousKey" value="${anonymousKey}"/>
+    <property name="userDetailsService" ref="syncopeUserDetailsService"/>
+  </bean>
+
+  <security:authentication-manager>
+    <security:authentication-provider ref="syncopeAuthenticationProvider"/>
+  </security:authentication-manager>
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
----------------------------------------------------------------------
diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
new file mode 100644
index 0000000..4bfa0fa
--- /dev/null
+++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spring.security;
+
+import org.apache.syncope.core.spring.security.Encryptor;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.junit.Test;
+
+/**
+ * Test class to test all encryption algorithms.
+ */
+public class EncryptorTest {
+
+    private final String password = "password";
+
+    private final Encryptor encryptor = Encryptor.getInstance();
+
+    /**
+     * Verify all algorithms.
+     */
+    @Test
+    public void testEncoder() throws Exception {
+        for (CipherAlgorithm cipherAlgorithm : CipherAlgorithm.values()) {
+            final String encPassword = encryptor.encode(password, cipherAlgorithm);
+
+            assertNotNull(encPassword);
+            assertTrue(encryptor.verify(password, cipherAlgorithm, encPassword));
+            assertFalse(encryptor.verify("pass", cipherAlgorithm, encPassword));
+
+            // check that same password encoded with BCRYPT or Salted versions results in different digest
+            if (cipherAlgorithm.equals(CipherAlgorithm.BCRYPT) || cipherAlgorithm.getAlgorithm().startsWith("S-")) {
+                final String encSamePassword = encryptor.encode(password, cipherAlgorithm);
+                assertNotNull(encSamePassword);
+                assertFalse(encSamePassword.equals(encPassword));
+                assertTrue(encryptor.verify(password, cipherAlgorithm, encSamePassword));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
----------------------------------------------------------------------
diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
new file mode 100644
index 0000000..02c0ba4
--- /dev/null
+++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.spring.security;
+
+import org.apache.syncope.core.spring.security.DefaultPasswordGenerator;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
+import org.junit.Test;
+
+public class PasswordGeneratorTest {
+
+    private final DefaultPasswordGenerator passwordGenerator = new DefaultPasswordGenerator();
+
+    private DefaultPasswordRuleConf createBaseDefaultPasswordRuleConf() {
+        DefaultPasswordRuleConf baseDefaultPasswordRuleConf = new DefaultPasswordRuleConf();
+        baseDefaultPasswordRuleConf.setAlphanumericRequired(false);
+        baseDefaultPasswordRuleConf.setDigitRequired(false);
+        baseDefaultPasswordRuleConf.setLowercaseRequired(false);
+        baseDefaultPasswordRuleConf.setMaxLength(1000);
+        baseDefaultPasswordRuleConf.setMinLength(8);
+        baseDefaultPasswordRuleConf.setMustEndWithAlpha(false);
+        baseDefaultPasswordRuleConf.setMustEndWithDigit(false);
+        baseDefaultPasswordRuleConf.setMustEndWithNonAlpha(false);
+        baseDefaultPasswordRuleConf.setMustStartWithAlpha(false);
+        baseDefaultPasswordRuleConf.setMustStartWithDigit(false);
+        baseDefaultPasswordRuleConf.setMustStartWithNonAlpha(false);
+        baseDefaultPasswordRuleConf.setMustntEndWithAlpha(false);
+        baseDefaultPasswordRuleConf.setMustntEndWithDigit(false);
+        baseDefaultPasswordRuleConf.setMustntEndWithNonAlpha(false);
+        baseDefaultPasswordRuleConf.setMustntStartWithAlpha(false);
+        baseDefaultPasswordRuleConf.setMustntStartWithDigit(false);
+        baseDefaultPasswordRuleConf.setMustntStartWithNonAlpha(false);
+        baseDefaultPasswordRuleConf.setNonAlphanumericRequired(false);
+        baseDefaultPasswordRuleConf.setUppercaseRequired(false);
+        return baseDefaultPasswordRuleConf;
+    }
+
+    @Test
+    public void startEndWithDigit() throws InvalidPasswordRuleConf {
+        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf.setMustStartWithDigit(true);
+
+        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf2.setMustEndWithDigit(true);
+
+        List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+        ruleConfs.add(pwdRuleConf);
+        ruleConfs.add(pwdRuleConf2);
+        String generatedPassword = passwordGenerator.generate(ruleConfs);
+        assertTrue(Character.isDigit(generatedPassword.charAt(0)));
+        assertTrue(Character.isDigit(generatedPassword.charAt(generatedPassword.length() - 1)));
+    }
+
+    @Test
+    public void startWithDigitAndWithAlpha() throws InvalidPasswordRuleConf {
+        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf.setMustStartWithDigit(true);
+
+        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf2.setMustEndWithAlpha(true);
+
+        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+        pwdRuleConfs.add(pwdRuleConf);
+        pwdRuleConfs.add(pwdRuleConf2);
+        String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
+        assertTrue(Character.isDigit(generatedPassword.charAt(0)));
+        assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
+    }
+
+    @Test
+    public void passwordWithNonAlpha() throws InvalidPasswordRuleConf {
+        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf.setNonAlphanumericRequired(true);
+
+        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf2.setMustEndWithAlpha(true);
+
+        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+        pwdRuleConfs.add(pwdRuleConf);
+        pwdRuleConfs.add(pwdRuleConf2);
+        String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
+        assertTrue(PolicyPattern.NON_ALPHANUMERIC.matcher(generatedPassword).matches());
+        assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
+    }
+
+    @Test(expected = InvalidPasswordRuleConf.class)
+    public void incopatiblePolicies() throws InvalidPasswordRuleConf {
+        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf.setMinLength(12);
+
+        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+        pwdRuleConf.setMaxLength(10);
+
+        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+        pwdRuleConfs.add(pwdRuleConf);
+        pwdRuleConfs.add(pwdRuleConf2);
+        passwordGenerator.generate(pwdRuleConfs);
+    }
+
+    @Test
+    public void issueSYNCOPE678() {
+        String password = null;
+        try {
+            password = passwordGenerator.generate(Collections.<PasswordRuleConf>emptyList());
+        } catch (InvalidPasswordRuleConf e) {
+            fail(e.getMessage());
+        }
+        assertNotNull(password);
+
+        DefaultPasswordRuleConf ppSpec = createBaseDefaultPasswordRuleConf();
+        ppSpec.setMinLength(0);
+        password = null;
+        try {
+            password = passwordGenerator.generate(Collections.<PasswordRuleConf>singletonList(ppSpec));
+        } catch (InvalidPasswordRuleConf e) {
+            fail(e.getMessage());
+        }
+        assertNotNull(password);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/pom.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/pom.xml b/core/workflow-activiti/pom.xml
index 07395ef..7a26ca1 100644
--- a/core/workflow-activiti/pom.xml
+++ b/core/workflow-activiti/pom.xml
@@ -68,7 +68,7 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.syncope.core</groupId>
-      <artifactId>syncope-core-misc</artifactId>
+      <artifactId>syncope-core-spring</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
index 494a03e..e91f595 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
@@ -32,7 +32,7 @@ import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngine;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 4436c52..a8a65b6 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -63,8 +63,8 @@ import org.apache.syncope.common.lib.to.WorkflowFormTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.entity.user.User;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
index f851e08..72da026 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
@@ -32,7 +32,7 @@ import org.activiti.engine.RepositoryService;
 import org.activiti.engine.RuntimeService;
 import org.activiti.engine.TaskService;
 import org.activiti.engine.impl.ProcessEngineImpl;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
 
 /**
  * {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index 8070ac2..78c625e 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -25,7 +25,7 @@ under the License.
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">
 
-  <bean id="userWorkflowDef" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+  <bean id="userWorkflowDef" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${wf.directory}/userWorkflow.bpmn20.xml"/>
     <property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/deb/core/pom.xml
----------------------------------------------------------------------
diff --git a/deb/core/pom.xml b/deb/core/pom.xml
index 65e5031..b26cc9c 100644
--- a/deb/core/pom.xml
+++ b/deb/core/pom.xml
@@ -156,7 +156,7 @@ under the License.
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/misc/src/main/resources</directory>
+        <directory>${basedir}/../../core/spring/src/main/resources</directory>
         <includes>
           <include>security.properties</include>
         </includes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index e3401ca..3c72ed2 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -32,8 +32,8 @@ import javax.xml.transform.stream.StreamResult;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CamelEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 1a918a5..2c1fe6d 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.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
index 04b3952..d86e42b 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
@@ -29,7 +29,7 @@ import org.apache.camel.model.Constants;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.spring.SpringCamelContext;
 import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
 import org.slf4j.Logger;


[14/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
deleted file mode 100644
index e47efc8..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
+++ /dev/null
@@ -1,41 +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.misc.utils;
-
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-
-public final class EntityUtils {
-
-    public static <KEY, E extends Entity<KEY>> Transformer<E, KEY> keyTransformer() {
-        return new Transformer<E, KEY>() {
-
-            @Override
-            public KEY transform(final E input) {
-                return input.getKey();
-            }
-        };
-    }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private EntityUtils() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
deleted file mode 100644
index 76ba64f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
+++ /dev/null
@@ -1,47 +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.misc.utils;
-
-import org.apache.commons.lang3.exception.ExceptionUtils;
-
-public final class ExceptionUtils2 {
-
-    /**
-     * Uses commons lang's ExceptionUtils to provide a representation of the full stack trace of the given throwable.
-     *
-     * @param t throwable to build stack trace from
-     * @return a string representation of full stack trace of the given throwable
-     */
-    public static String getFullStackTrace(final Throwable t) {
-        StringBuilder result = new StringBuilder();
-
-        for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
-            result.append(ExceptionUtils.getMessage(throwable)).append('\n').
-                    append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private ExceptionUtils2() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
deleted file mode 100644
index 131f310..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.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.misc.utils;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import org.apache.commons.lang3.time.DateUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-
-/**
- * Utility class for parsing / formatting date and numbers.
- */
-public final class FormatUtils {
-
-    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-
-        @Override
-        protected SimpleDateFormat initialValue() {
-            SimpleDateFormat sdf = new SimpleDateFormat();
-            sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
-            return sdf;
-        }
-    };
-
-    private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
-
-        @Override
-        protected DecimalFormat initialValue() {
-            DecimalFormat df = new DecimalFormat();
-            df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
-            return df;
-        }
-    };
-
-    public static String format(final Date date) {
-        return format(date, true);
-    }
-
-    public static String format(final Date date, final boolean lenient) {
-        return format(date, lenient, null);
-    }
-
-    public static String format(final Date date, final boolean lenient, final String conversionPattern) {
-        SimpleDateFormat sdf = DATE_FORMAT.get();
-        if (conversionPattern != null) {
-            sdf.applyPattern(conversionPattern);
-        }
-        sdf.setLenient(lenient);
-        return sdf.format(date);
-    }
-
-    public static String format(final long number) {
-        return format(number, null);
-    }
-
-    public static String format(final long number, final String conversionPattern) {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        if (conversionPattern != null) {
-            df.applyPattern(conversionPattern);
-        }
-        return df.format(number);
-    }
-
-    public static String format(final double number) {
-        return format(number, null);
-    }
-
-    public static String format(final double number, final String conversionPattern) {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        if (conversionPattern != null) {
-            df.applyPattern(conversionPattern);
-        }
-        return df.format(number);
-    }
-
-    public static Date parseDate(final String source) throws ParseException {
-        return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
-    }
-
-    public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
-        SimpleDateFormat sdf = DATE_FORMAT.get();
-        sdf.applyPattern(conversionPattern);
-        sdf.setLenient(false);
-        return sdf.parse(source);
-    }
-
-    public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        df.applyPattern(conversionPattern);
-        return df.parse(source);
-    }
-
-    public static void clear() {
-        DATE_FORMAT.remove();
-        DECIMAL_FORMAT.remove();
-    }
-
-    private FormatUtils() {
-        // private empty constructor
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
deleted file mode 100644
index b3102af..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
+++ /dev/null
@@ -1,841 +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.misc.utils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.collections4.ListUtils;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-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.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-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.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-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.provisioning.api.DerAttrHandler;
-import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.identityconnectors.framework.common.FrameworkUtil;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.AttributeUtil;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.OperationOptions;
-import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class MappingUtils {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MappingUtils.class);
-
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private DerAttrHandler derAttrHandler;
-
-    @Autowired
-    private VirAttrHandler virAttrHandler;
-
-    @Autowired
-    private VirAttrCache virAttrCache;
-
-    @Autowired
-    private PasswordGenerator passwordGenerator;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
-    public static MappingItem getConnObjectKeyItem(final Provision provision) {
-        Mapping mapping = null;
-        if (provision != null) {
-            mapping = provision.getMapping();
-        }
-
-        return mapping == null
-                ? null
-                : mapping.getConnObjectKeyItem();
-    }
-
-    private static List<MappingItem> getMappingItems(final Provision provision, final MappingPurpose purpose) {
-        List<? extends MappingItem> items = Collections.<MappingItem>emptyList();
-        if (provision != null) {
-            items = provision.getMapping().getItems();
-        }
-
-        List<MappingItem> result = new ArrayList<>();
-
-        switch (purpose) {
-            case SYNCHRONIZATION:
-                for (MappingItem item : items) {
-                    if (MappingPurpose.PROPAGATION != item.getPurpose()
-                            && MappingPurpose.NONE != item.getPurpose()) {
-
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case PROPAGATION:
-                for (MappingItem item : items) {
-                    if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
-                            && MappingPurpose.NONE != item.getPurpose()) {
-
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case BOTH:
-                for (MappingItem item : items) {
-                    if (MappingPurpose.NONE != item.getPurpose()) {
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case NONE:
-                for (MappingItem item : items) {
-                    if (MappingPurpose.NONE == item.getPurpose()) {
-                        result.add(item);
-                    }
-                }
-                break;
-
-            default:
-        }
-
-        return result;
-    }
-
-    public static List<MappingItem> getBothMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.BOTH);
-    }
-
-    public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.PROPAGATION);
-    }
-
-    public static List<MappingItem> getSyncMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.SYNCHRONIZATION);
-    }
-
-    /**
-     * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
-     * this case evaluate as JEXL); otherwise, take given connObjectKey.
-     *
-     * @param any given any object
-     * @param provision external resource
-     * @param connObjectKey connector object key
-     * @return the value to be propagated as __NAME__
-     */
-    public static Name evaluateNAME(final Any<?> any, final Provision provision, final String connObjectKey) {
-        if (StringUtils.isBlank(connObjectKey)) {
-            // LOG error but avoid to throw exception: leave it to the external resource
-            LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
-        }
-
-        // Evaluate connObjectKey expression
-        String connObjectLink = provision == null || provision.getMapping() == null
-                ? null
-                : provision.getMapping().getConnObjectLink();
-        String evalConnObjectLink = null;
-        if (StringUtils.isNotBlank(connObjectLink)) {
-            JexlContext jexlContext = new MapContext();
-            JexlUtils.addFieldsToContext(any, jexlContext);
-            JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
-            JexlUtils.addDerAttrsToContext(any, jexlContext);
-            evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
-        }
-
-        // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
-        // otherwise evaluated connObjectLink expression is taken as Name().
-        Name name;
-        if (StringUtils.isBlank(evalConnObjectLink)) {
-            // add connObjectKey as __NAME__ attribute ...
-            LOG.debug("Add connObjectKey [{}] as __NAME__", connObjectKey);
-            name = new Name(connObjectKey);
-        } else {
-            LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
-            name = new Name(evalConnObjectLink);
-
-            // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
-            LOG.debug("connObjectKey will be used just as __UID__ attribute");
-        }
-
-        return name;
-    }
-
-    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
-        List<MappingItemTransformer> result = new ArrayList<>();
-
-        for (String className : mappingItem.getMappingItemTransformerClassNames()) {
-            try {
-                Class<?> transformerClass = ClassUtils.getClass(className);
-
-                result.add((MappingItemTransformer) ApplicationContextProvider.
-                        getBeanFactory().
-                        createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
-            } catch (Exception e) {
-                LOG.error("Could not instantiate {}, ignoring...", className, e);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Build options for requesting all mapped connector attributes.
-     *
-     * @param mapItems mapping items
-     * @return options for requesting all mapped connector attributes
-     * @see OperationOptions
-     */
-    public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
-        OperationOptionsBuilder builder = new OperationOptionsBuilder();
-
-        Set<String> attrsToGet = new HashSet<>();
-        attrsToGet.add(Name.NAME);
-        attrsToGet.add(Uid.NAME);
-        attrsToGet.add(OperationalAttributes.ENABLE_NAME);
-
-        while (mapItems.hasNext()) {
-            MappingItem mapItem = mapItems.next();
-            if (mapItem.getPurpose() != MappingPurpose.NONE) {
-                attrsToGet.add(mapItem.getExtAttrName());
-            }
-        }
-
-        builder.setAttributesToGet(attrsToGet);
-        // -------------------------------------
-
-        return builder.build();
-    }
-
-    /**
-     * Prepare attributes for sending to a connector instance.
-     *
-     * @param any given any object
-     * @param password clear-text password
-     * @param changePwd whether password should be included for propagation attributes or not
-     * @param enable whether any object must be enabled or not
-     * @param provision provision information
-     * @return connObjectLink + prepared attributes
-     */
-    @Transactional(readOnly = true)
-    public Pair<String, Set<Attribute>> prepareAttrs(
-            final Any<?> any,
-            final String password,
-            final boolean changePwd,
-            final Boolean enable,
-            final Provision provision) {
-
-        LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
-                any, provision, any.getPlainAttrs());
-
-        Set<Attribute> attributes = new HashSet<>();
-        String connObjectKey = null;
-
-        for (MappingItem mappingItem : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
-            LOG.debug("Processing schema {}", mappingItem.getIntAttrName());
-
-            try {
-                Pair<String, Attribute> preparedAttr = prepareAttr(provision, mappingItem, any, password);
-
-                if (preparedAttr != null && preparedAttr.getKey() != null) {
-                    connObjectKey = preparedAttr.getKey();
-                }
-
-                if (preparedAttr != null && preparedAttr.getValue() != null) {
-                    Attribute alreadyAdded = AttributeUtil.find(preparedAttr.getValue().getName(), attributes);
-
-                    if (alreadyAdded == null) {
-                        attributes.add(preparedAttr.getValue());
-                    } else {
-                        attributes.remove(alreadyAdded);
-
-                        Set<Object> values = new HashSet<>(alreadyAdded.getValue());
-                        values.addAll(preparedAttr.getValue().getValue());
-
-                        attributes.add(AttributeBuilder.build(preparedAttr.getValue().getName(), values));
-                    }
-                }
-            } catch (Exception e) {
-                LOG.debug("Attribute '{}' processing failed", mappingItem.getIntAttrName(), e);
-            }
-        }
-
-        Attribute connObjectKeyExtAttr =
-                AttributeUtil.find(getConnObjectKeyItem(provision).getExtAttrName(), attributes);
-        if (connObjectKeyExtAttr != null) {
-            attributes.remove(connObjectKeyExtAttr);
-            attributes.add(AttributeBuilder.build(getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
-        }
-        attributes.add(evaluateNAME(any, provision, connObjectKey));
-
-        if (enable != null) {
-            attributes.add(AttributeBuilder.buildEnabled(enable));
-        }
-        if (!changePwd) {
-            Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes);
-            if (pwdAttr != null) {
-                attributes.remove(pwdAttr);
-            }
-        }
-
-        return new ImmutablePair<>(connObjectKey, attributes);
-    }
-
-    /**
-     * Prepare an attribute to be sent to a connector instance.
-     *
-     * @param provision external resource
-     * @param mapItem mapping item for the given attribute
-     * @param any any object
-     * @param password clear-text password
-     * @return connObjectKey + prepared attribute
-     */
-    private Pair<String, Attribute> prepareAttr(
-            final Provision provision, final MappingItem mapItem, final Any<?> any, final String password) {
-
-        List<Any<?>> anys = new ArrayList<>();
-
-        switch (mapItem.getIntMappingType().getAnyTypeKind()) {
-            case USER:
-                if (any instanceof User) {
-                    anys.add(any);
-                }
-                break;
-
-            case GROUP:
-                if (any instanceof User) {
-                    for (Group group : userDAO.findAllGroups((User) any)) {
-                        anys.add(group);
-                    }
-                } else if (any instanceof Group) {
-                    anys.add(any);
-                }
-                break;
-
-            case ANY_OBJECT:
-                if (any instanceof AnyObject) {
-                    anys.add(any);
-                }
-                break;
-
-            default:
-        }
-
-        Schema schema = null;
-        boolean readOnlyVirSchema = false;
-        AttrSchemaType schemaType;
-        Pair<String, Attribute> result;
-
-        switch (mapItem.getIntMappingType()) {
-            case UserPlainSchema:
-            case GroupPlainSchema:
-            case AnyObjectPlainSchema:
-                schema = plainSchemaDAO.find(mapItem.getIntAttrName());
-                schemaType = schema == null ? AttrSchemaType.String : schema.getType();
-                break;
-
-            case UserVirtualSchema:
-            case GroupVirtualSchema:
-            case AnyObjectVirtualSchema:
-                schema = virSchemaDAO.find(mapItem.getIntAttrName());
-                readOnlyVirSchema = (schema != null && schema.isReadonly());
-                schemaType = AttrSchemaType.String;
-                break;
-
-            default:
-                schemaType = AttrSchemaType.String;
-        }
-
-        String extAttrName = mapItem.getExtAttrName();
-
-        List<PlainAttrValue> values = getIntValues(provision, mapItem, anys);
-
-        LOG.debug("Define mapping for: "
-                + "\n* ExtAttrName " + extAttrName
-                + "\n* is connObjectKey " + mapItem.isConnObjectKey()
-                + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
-                + "\n* mandatory condition " + mapItem.getMandatoryCondition()
-                + "\n* Schema " + mapItem.getIntAttrName()
-                + "\n* IntMappingType " + mapItem.getIntMappingType().toString()
-                + "\n* ClassType " + schemaType.getType().getName()
-                + "\n* Values " + values);
-
-        if (readOnlyVirSchema) {
-            result = null;
-        } else {
-            List<Object> objValues = new ArrayList<>();
-
-            for (PlainAttrValue value : values) {
-                if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) {
-                    objValues.add(value.getValue());
-                } else {
-                    objValues.add(value.getValueAsString());
-                }
-            }
-
-            if (mapItem.isConnObjectKey()) {
-                result = new ImmutablePair<>(objValues.iterator().next().toString(), null);
-            } else if (mapItem.isPassword() && any instanceof User) {
-                String passwordAttrValue = password;
-                if (StringUtils.isBlank(passwordAttrValue)) {
-                    User user = (User) any;
-                    if (user.canDecodePassword()) {
-                        try {
-                            passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
-                        } catch (Exception e) {
-                            LOG.error("Could not decode password for {}", user, e);
-                        }
-                    } else if (provision.getResource().isRandomPwdIfNotProvided()) {
-                        try {
-                            passwordAttrValue = passwordGenerator.generate(user);
-                        } catch (InvalidPasswordRuleConf e) {
-                            LOG.error("Could not generate policy-compliant random password for {}", user, e);
-                        }
-                    }
-                }
-
-                if (passwordAttrValue == null) {
-                    result = null;
-                } else {
-                    result = new ImmutablePair<>(
-                            null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
-                }
-            } else if ((schema != null && schema.isMultivalue())
-                    || anyUtilsFactory.getInstance(any).getAnyTypeKind()
-                    != mapItem.getIntMappingType().getAnyTypeKind()) {
-
-                result = new ImmutablePair<>(
-                        null, AttributeBuilder.build(extAttrName, objValues));
-            } else {
-                result = new ImmutablePair<>(
-                        null, objValues.isEmpty()
-                                ? AttributeBuilder.build(extAttrName)
-                                : AttributeBuilder.build(extAttrName, objValues.iterator().next()));
-            }
-        }
-
-        return result;
-    }
-
-    private String getGroupOwnerValue(final Provision provision, final Any<?> any) {
-        Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision), any, null);
-        String connObjectKey = preparedAttr.getKey();
-
-        return evaluateNAME(any, provision, connObjectKey).getNameValue();
-    }
-
-    /**
-     * Get attribute values for the given {@link MappingItem} and any objects.
-     *
-     * @param provision provision information
-     * @param mappingItem mapping item
-     * @param anys any objects
-     * @return attribute values.
-     */
-    @Transactional(readOnly = true)
-    public List<PlainAttrValue> getIntValues(final Provision provision,
-            final MappingItem mappingItem, final List<Any<?>> anys) {
-
-        LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
-
-        boolean transform = true;
-
-        List<PlainAttrValue> values = new ArrayList<>();
-        switch (mappingItem.getIntMappingType()) {
-            case UserPlainSchema:
-            case GroupPlainSchema:
-            case AnyObjectPlainSchema:
-                for (Any<?> any : anys) {
-                    PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
-                    if (attr != null) {
-                        if (attr.getUniqueValue() != null) {
-                            PlainAttrUniqueValue value = SerializationUtils.clone(attr.getUniqueValue());
-                            value.setAttr(null);
-                            values.add(value);
-                        } else if (attr.getValues() != null) {
-                            for (PlainAttrValue value : attr.getValues()) {
-                                PlainAttrValue shadow = SerializationUtils.clone(value);
-                                shadow.setAttr(null);
-                                values.add(shadow);
-                            }
-                        }
-                    }
-
-                    LOG.debug("Retrieved attribute {}"
-                            + "\n* IntAttrName {}"
-                            + "\n* IntMappingType {}"
-                            + "\n* Attribute values {}",
-                            attr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
-                }
-
-                break;
-
-            case UserDerivedSchema:
-            case GroupDerivedSchema:
-            case AnyObjectDerivedSchema:
-                DerSchema derSchema = derSchemaDAO.find(mappingItem.getIntAttrName());
-                if (derSchema != null) {
-                    for (Any<?> any : anys) {
-                        String value = derAttrHandler.getValue(any, derSchema);
-                        if (value != null) {
-                            AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                            attrValue.setStringValue(value);
-                            values.add(attrValue);
-
-                            LOG.debug("Retrieved values for {}"
-                                    + "\n* IntAttrName {}"
-                                    + "\n* IntMappingType {}"
-                                    + "\n* Attribute values {}",
-                                    derSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
-                                    values);
-                        }
-                    }
-                }
-                break;
-
-            case UserVirtualSchema:
-            case GroupVirtualSchema:
-            case AnyObjectVirtualSchema:
-                // virtual attributes don't get transformed
-                transform = false;
-
-                VirSchema virSchema = virSchemaDAO.find(mappingItem.getIntAttrName());
-                if (virSchema != null) {
-                    for (Any<?> any : anys) {
-                        LOG.debug("Expire entry cache {}-{}", any.getKey(), mappingItem.getIntAttrName());
-                        virAttrCache.expire(any.getType().getKey(), any.getKey(), mappingItem.getIntAttrName());
-
-                        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-                        for (String value : virAttrHandler.getValues(any, virSchema)) {
-                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                            attrValue.setStringValue(value);
-                            values.add(attrValue);
-                        }
-
-                        LOG.debug("Retrieved values for {}"
-                                + "\n* IntAttrName {}"
-                                + "\n* IntMappingType {}"
-                                + "\n* Attribute values {}",
-                                virSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
-                                values);
-                    }
-                }
-                break;
-
-            case UserKey:
-            case GroupKey:
-            case AnyObjectKey:
-                for (Any<?> any : anys) {
-                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-                    PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                    attrValue.setStringValue(any.getKey().toString());
-                    values.add(attrValue);
-                }
-                break;
-
-            case Username:
-                for (Any<?> any : anys) {
-                    if (any instanceof User) {
-                        UPlainAttrValue attrValue = entityFactory.newEntity(UPlainAttrValue.class);
-                        attrValue.setStringValue(((User) any).getUsername());
-                        values.add(attrValue);
-                    }
-                }
-                break;
-
-            case GroupName:
-                for (Any<?> any : anys) {
-                    if (any instanceof Group) {
-                        GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
-                        attrValue.setStringValue(((Group) any).getName());
-                        values.add(attrValue);
-                    }
-                }
-                break;
-
-            case GroupOwnerSchema:
-                Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
-                        ? provision.getMapping()
-                        : null;
-                Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
-                        ? provision.getMapping()
-                        : null;
-
-                for (Any<?> any : anys) {
-                    if (any instanceof Group) {
-                        Group group = (Group) any;
-                        String groupOwnerValue = null;
-                        if (group.getUserOwner() != null && uMapping != null) {
-                            groupOwnerValue = getGroupOwnerValue(provision, group.getUserOwner());
-                        }
-                        if (group.getGroupOwner() != null && gMapping != null) {
-                            groupOwnerValue = getGroupOwnerValue(provision, group.getGroupOwner());
-                        }
-
-                        if (StringUtils.isNotBlank(groupOwnerValue)) {
-                            GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
-                            attrValue.setStringValue(groupOwnerValue);
-                            values.add(attrValue);
-                        }
-                    }
-                }
-                break;
-
-            default:
-        }
-
-        LOG.debug("Values for propagation: {}", values);
-
-        List<PlainAttrValue> transformed = values;
-        if (transform) {
-            for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
-                transformed = transformer.beforePropagation(transformed);
-            }
-            LOG.debug("Transformed values for propagation: {}", values);
-        } else {
-            LOG.debug("No transformation occurred");
-        }
-
-        return transformed;
-    }
-
-    /**
-     * Get connObjectKey internal value.
-     *
-     * @param any any object
-     * @param provision provision information
-     * @return connObjectKey internal value
-     */
-    @Transactional(readOnly = true)
-    public String getConnObjectKeyValue(final Any<?> any, final Provision provision) {
-        List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
-                Collections.<Any<?>>singletonList(any));
-        return values == null || values.isEmpty()
-                ? null
-                : values.get(0).getValueAsString();
-    }
-
-    /**
-     * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
-     * connector.
-     *
-     * @param <T> any object
-     * @param mappingItem mapping item
-     * @param attr attribute received from connector
-     * @param anyTO any object
-     * @param anyUtils any utils
-     */
-    @Transactional(readOnly = true)
-    public <T extends AnyTO> void setIntValues(
-            final MappingItem mappingItem, final Attribute attr, final T anyTO, final AnyUtils anyUtils) {
-
-        List<Object> values = null;
-        if (attr != null) {
-            values = attr.getValue();
-            for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
-                values = transformer.beforeSync(values);
-            }
-        }
-        values = ListUtils.emptyIfNull(values);
-
-        switch (mappingItem.getIntMappingType()) {
-            case UserKey:
-            case GroupKey:
-            case AnyObjectKey:
-                break;
-
-            case Password:
-                if (anyTO instanceof UserTO && !values.isEmpty()) {
-                    ((UserTO) anyTO).setPassword(ConnObjectUtils.getPassword(values.get(0)));
-                }
-                break;
-
-            case Username:
-                if (anyTO instanceof UserTO) {
-                    ((UserTO) anyTO).setUsername(values.isEmpty() || values.get(0) == null
-                            ? null
-                            : values.get(0).toString());
-                }
-                break;
-
-            case GroupName:
-                if (anyTO instanceof GroupTO) {
-                    ((GroupTO) anyTO).setName(values.isEmpty() || values.get(0) == null
-                            ? null
-                            : values.get(0).toString());
-                }
-                break;
-
-            case GroupOwnerSchema:
-                if (anyTO instanceof GroupTO && attr != null) {
-                    // using a special attribute (with schema "", that will be ignored) for carrying the
-                    // GroupOwnerSchema value
-                    AttrTO attrTO = new AttrTO();
-                    attrTO.setSchema(StringUtils.EMPTY);
-                    if (values.isEmpty() || values.get(0) == null) {
-                        attrTO.getValues().add(StringUtils.EMPTY);
-                    } else {
-                        attrTO.getValues().add(values.get(0).toString());
-                    }
-
-                    ((GroupTO) anyTO).getPlainAttrs().add(attrTO);
-                }
-                break;
-
-            case UserPlainSchema:
-            case GroupPlainSchema:
-            case AnyObjectPlainSchema:
-                AttrTO attrTO = new AttrTO();
-                attrTO.setSchema(mappingItem.getIntAttrName());
-
-                PlainSchema schema = plainSchemaDAO.find(mappingItem.getIntAttrName());
-
-                for (Object value : values) {
-                    AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
-                    if (value != null) {
-                        PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                        switch (schemaType) {
-                            case String:
-                                attrValue.setStringValue(value.toString());
-                                break;
-
-                            case Binary:
-                                attrValue.setBinaryValue((byte[]) value);
-                                break;
-
-                            default:
-                                try {
-                                    attrValue.parseValue(schema, value.toString());
-                                } catch (ParsingValidationException e) {
-                                    LOG.error("While parsing provided value {}", value, e);
-                                    attrValue.setStringValue(value.toString());
-                                    schemaType = AttrSchemaType.String;
-                                }
-                                break;
-                        }
-                        attrTO.getValues().add(attrValue.getValueAsString(schemaType));
-                    }
-                }
-
-                anyTO.getPlainAttrs().add(attrTO);
-                break;
-
-            case UserDerivedSchema:
-            case GroupDerivedSchema:
-            case AnyObjectDerivedSchema:
-                attrTO = new AttrTO();
-                attrTO.setSchema(mappingItem.getIntAttrName());
-                anyTO.getDerAttrs().add(attrTO);
-                break;
-
-            case UserVirtualSchema:
-            case GroupVirtualSchema:
-            case AnyObjectVirtualSchema:
-                attrTO = new AttrTO();
-                attrTO.setSchema(mappingItem.getIntAttrName());
-
-                // virtual attributes don't get transformed, iterate over original attr.getValue()
-                for (Object value : (attr == null || attr.getValue() == null)
-                        ? Collections.emptyList() : attr.getValue()) {
-
-                    if (value != null) {
-                        attrTO.getValues().add(value.toString());
-                    }
-                }
-
-                anyTO.getVirAttrs().add(attrTO);
-                break;
-
-            default:
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
deleted file mode 100644
index f3c0a46..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
+++ /dev/null
@@ -1,63 +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.misc.utils;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-public final class RealmUtils {
-
-    public static String getGroupOwnerRealm(final String realmPath, final Long groupKey) {
-        return realmPath + "@" + groupKey;
-    }
-
-    public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {
-        boolean dontAdd = false;
-        Set<String> toRemove = new HashSet<>();
-        for (String realm : realms) {
-            if (newRealm.startsWith(realm)) {
-                dontAdd = true;
-            } else if (realm.startsWith(newRealm)) {
-                toRemove.add(realm);
-            }
-        }
-
-        realms.removeAll(toRemove);
-        if (!dontAdd) {
-            realms.add(newRealm);
-        }
-        return !dontAdd;
-    }
-
-    public static Set<String> normalize(final Collection<String> realms) {
-        Set<String> normalized = new HashSet<>();
-        if (realms != null) {
-            for (String realm : realms) {
-                normalizingAddTo(normalized, realm);
-            }
-        }
-
-        return normalized;
-    }
-
-    private RealmUtils() {
-        // empty constructor for static utility class 
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
deleted file mode 100644
index e09e0e2..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
+++ /dev/null
@@ -1,224 +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.misc.utils;
-
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.RelationshipTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-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.AnyTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class TemplateUtils {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    private AttrTO evaluateAttr(final AnyTO anyTO, final AttrTO template) {
-        AttrTO result = new AttrTO();
-        result.setSchema(template.getSchema());
-
-        if (template.getValues() != null && !template.getValues().isEmpty()) {
-            for (String value : template.getValues()) {
-                String evaluated = JexlUtils.evaluate(value, anyTO);
-                if (StringUtils.isNotBlank(evaluated)) {
-                    result.getValues().add(evaluated);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    private void fill(final AnyTO anyTO, final AnyTO template) {
-        if (template.getRealm() != null) {
-            anyTO.setRealm(template.getRealm());
-        }
-
-        Map<String, AttrTO> currentAttrMap = anyTO.getPlainAttrMap();
-        for (AttrTO templatePlainAttr : template.getPlainAttrs()) {
-            if (!templatePlainAttr.getValues().isEmpty()
-                    && (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
-                    || currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
-
-                anyTO.getPlainAttrs().add(evaluateAttr(anyTO, templatePlainAttr));
-            }
-        }
-
-        currentAttrMap = anyTO.getDerAttrMap();
-        for (AttrTO templateDerAttr : template.getDerAttrs()) {
-            if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
-                anyTO.getDerAttrs().add(templateDerAttr);
-            }
-        }
-
-        currentAttrMap = anyTO.getVirAttrMap();
-        for (AttrTO templateVirAttr : template.getVirAttrs()) {
-            if (!templateVirAttr.getValues().isEmpty()
-                    && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
-                    || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
-
-                anyTO.getVirAttrs().add(evaluateAttr(anyTO, templateVirAttr));
-            }
-        }
-
-        for (String resource : template.getResources()) {
-            anyTO.getResources().add(resource);
-        }
-
-        anyTO.getAuxClasses().addAll(template.getAuxClasses());
-    }
-
-    private void fillRelationships(final Map<Pair<String, Long>, RelationshipTO> anyRelMap,
-            final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
-
-        for (RelationshipTO memb : templateRels) {
-            if (!anyRelMap.containsKey(Pair.of(memb.getRightType(), memb.getRightKey()))) {
-                anyRels.add(memb);
-            }
-        }
-    }
-
-    private void fillMemberships(final Map<Long, MembershipTO> anyMembMap,
-            final List<MembershipTO> anyMembs, final List<MembershipTO> templateMembs) {
-
-        for (MembershipTO memb : templateMembs) {
-            if (!anyMembMap.containsKey(memb.getRightKey())) {
-                anyMembs.add(memb);
-            }
-        }
-    }
-
-    @Transactional(readOnly = true)
-    public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
-        if (anyTemplate != null) {
-            AnyTO template = anyTemplate.get();
-            fill(anyTO, template);
-
-            if (template instanceof AnyObjectTO) {
-                fillRelationships(((AnyObjectTO) anyTO).getRelationshipMap(),
-                        ((AnyObjectTO) anyTO).getRelationships(), ((AnyObjectTO) template).getRelationships());
-                fillMemberships(((AnyObjectTO) anyTO).getMembershipMap(),
-                        ((AnyObjectTO) anyTO).getMemberships(), ((AnyObjectTO) template).getMemberships());
-            } else if (template instanceof UserTO) {
-                if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
-                    String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
-                    if (StringUtils.isNotBlank(evaluated)) {
-                        ((UserTO) anyTO).setUsername(evaluated);
-                    }
-                }
-
-                if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
-                    String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO);
-                    if (StringUtils.isNotBlank(evaluated)) {
-                        ((UserTO) anyTO).setPassword(evaluated);
-                    }
-                }
-
-                fillRelationships(((UserTO) anyTO).getRelationshipMap(),
-                        ((UserTO) anyTO).getRelationships(), ((UserTO) template).getRelationships());
-                fillMemberships(((UserTO) anyTO).getMembershipMap(),
-                        ((UserTO) anyTO).getMemberships(), ((UserTO) template).getMemberships());
-            } else if (template instanceof GroupTO) {
-                if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
-                    String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
-                    if (StringUtils.isNotBlank(evaluated)) {
-                        ((GroupTO) anyTO).setName(evaluated);
-                    }
-                }
-
-                if (((GroupTO) template).getUserOwner() != null) {
-                    final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
-                    if (userOwner != null) {
-                        ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
-                    }
-                }
-                if (((GroupTO) template).getGroupOwner() != null) {
-                    final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
-                    if (groupOwner != null) {
-                        ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
-                    }
-                }
-            }
-        }
-    }
-
-    public void check(final Map<String, AnyTO> templates, final ClientExceptionType clientExceptionType) {
-        SyncopeClientException sce = SyncopeClientException.build(clientExceptionType);
-
-        for (Map.Entry<String, AnyTO> entry : templates.entrySet()) {
-            for (AttrTO attrTO : entry.getValue().getPlainAttrs()) {
-                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
-                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
-                }
-            }
-
-            for (AttrTO attrTO : entry.getValue().getVirAttrs()) {
-                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
-                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
-                }
-            }
-
-            if (entry.getValue() instanceof UserTO) {
-                UserTO template = (UserTO) entry.getValue();
-                if (StringUtils.isNotBlank(template.getUsername())
-                        && !JexlUtils.isExpressionValid(template.getUsername())) {
-
-                    sce.getElements().add("Invalid JEXL: " + template.getUsername());
-                }
-                if (StringUtils.isNotBlank(template.getPassword())
-                        && !JexlUtils.isExpressionValid(template.getPassword())) {
-
-                    sce.getElements().add("Invalid JEXL: " + template.getPassword());
-                }
-            } else if (entry.getValue() instanceof GroupTO) {
-                GroupTO template = (GroupTO) entry.getValue();
-                if (StringUtils.isNotBlank(template.getName())
-                        && !JexlUtils.isExpressionValid(template.getName())) {
-
-                    sce.getElements().add("Invalid JEXL: " + template.getName());
-                }
-            }
-        }
-
-        if (!sce.isEmpty()) {
-            throw sce;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/security.properties
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/security.properties b/core/misc/src/main/resources/security.properties
deleted file mode 100644
index 73db510..0000000
--- a/core/misc/src/main/resources/security.properties
+++ /dev/null
@@ -1,32 +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.
-adminUser=admin
-adminPassword=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
-adminPasswordAlgorithm=SHA1
-
-anonymousUser=${anonymousUser}
-anonymousKey=${anonymousKey}
-
-secretKey=${secretKey}
-# default for LDAP / RFC2307 SSHA
-digester.saltIterations=1
-digester.saltSizeBytes=8
-digester.invertPositionOfPlainSaltInEncryptionResults=true
-digester.invertPositionOfSaltInMessageBeforeDigesting=true
-digester.useLenientSaltSizeCheck=true
-
-passwordGenerator=org.apache.syncope.core.misc.security.DefaultPasswordGenerator

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/securityContext.xml b/core/misc/src/main/resources/securityContext.xml
deleted file mode 100644
index 222d64a..0000000
--- a/core/misc/src/main/resources/securityContext.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:security="http://www.springframework.org/schema/security"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/security
-                           http://www.springframework.org/schema/security/spring-security.xsd">
-
-  <bean id="adminUser" class="java.lang.String">
-    <constructor-arg value="${adminUser}"/>
-  </bean>
-  <bean id="anonymousUser" class="java.lang.String">
-    <constructor-arg value="${anonymousUser}"/>
-  </bean>
-  
-  <bean class="${passwordGenerator}"/>
-  <bean class="org.apache.syncope.core.misc.spring.DefaultRolesPrefixPostProcessor"/>
-  
-  <security:global-method-security pre-post-annotations="enabled"/>
-  
-  <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
-    <security:filter-chain-map request-matcher="ant">
-      <security:filter-chain pattern="/**" filters="securityContextPersistenceFilter"/>
-    </security:filter-chain-map>
-  </bean>
-  
-  <bean id="securityContextRepository" class='org.springframework.security.web.context.NullSecurityContextRepository'/>
-
-  <bean id="securityContextPersistenceFilter"
-        class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
-    <constructor-arg ref="securityContextRepository"/>
-  </bean>
-
-  <bean id="syncopeAuthenticationDetailsSource"
-        class="org.apache.syncope.core.misc.security.SyncopeAuthenticationDetailsSource"/>
-
-  <bean id="mustChangePasswordFilter" class="org.apache.syncope.core.misc.security.MustChangePasswordFilter"/>
-      
-  <bean id="syncopeAuthenticationEntryPoint" 
-        class="org.apache.syncope.core.misc.security.SyncopeAuthenticationEntryPoint">
-    <property name="realmName" value="Apache Syncope authentication"/>
-  </bean>
-
-  <bean id="syncopeAccessDeniedHandler" class="org.apache.syncope.core.misc.security.SyncopeAccessDeniedHandler"/>
-  
-  <security:http security-context-repository-ref="securityContextRepository"
-                 use-expressions="false" disable-url-rewriting="false">
-
-    <security:http-basic entry-point-ref="syncopeAuthenticationEntryPoint"
-                         authentication-details-source-ref="syncopeAuthenticationDetailsSource"/>
-    <security:anonymous username="${anonymousUser}"/>
-    <security:intercept-url pattern="/**"/>
-    
-    <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="mustChangePasswordFilter"/>
-    
-    <security:access-denied-handler ref="syncopeAccessDeniedHandler"/>
-    
-    <security:headers disabled="true"/>
-    <security:csrf disabled="true"/>
-  </security:http>
-
-  <bean class="org.apache.syncope.core.misc.security.AuthDataAccessor"/>
-
-  <bean id="syncopeUserDetailsService" class="org.apache.syncope.core.misc.security.SyncopeUserDetailsService"/>
-
-  <bean id="syncopeAuthenticationProvider" class="org.apache.syncope.core.misc.security.SyncopeAuthenticationProvider">
-    <property name="adminPassword" value="${adminPassword}"/>
-    <property name="adminPasswordAlgorithm" value="${adminPasswordAlgorithm}"/>
-    <property name="anonymousKey" value="${anonymousKey}"/>
-    <property name="userDetailsService" ref="syncopeUserDetailsService"/>
-  </bean>
-
-  <security:authentication-manager>
-    <security:authentication-provider ref="syncopeAuthenticationProvider"/>
-  </security:authentication-manager>
-</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/utilsContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/utilsContext.xml b/core/misc/src/main/resources/utilsContext.xml
deleted file mode 100644
index 7b2c9b3..0000000
--- a/core/misc/src/main/resources/utilsContext.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd">
-
-  <bean class="org.apache.syncope.core.misc.AuditManager"/>
-
-  <context:component-scan base-package="org.apache.syncope.core.misc.utils"/>  
-
-</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
deleted file mode 100644
index 189b575..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ /dev/null
@@ -1,226 +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.misc.search;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.search.SpecialAttr;
-import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
-import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
-import org.junit.Test;
-
-public class SearchCondConverterTest {
-
-    @Test
-    public void eq() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
-        assertEquals("username==rossini", fiqlExpression);
-
-        AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
-        attrCond.setSchema("username");
-        attrCond.setExpression("rossini");
-        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void like() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
-        assertEquals("username==ros*", fiqlExpression);
-
-        AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
-        attrCond.setSchema("username");
-        attrCond.setExpression("ros%");
-        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void isNull() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
-        assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
-
-        AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
-        attrCond.setSchema("loginDate");
-        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void isNotNull() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
-        assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
-
-        AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
-        attrCond.setSchema("loginDate");
-        SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void relationships() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationships(1L).query();
-        assertEquals(SpecialAttr.RELATIONSHIPS + "==1", fiqlExpression);
-
-        RelationshipCond relationshipCond = new RelationshipCond();
-        relationshipCond.setAnyObjectKey(1L);
-        SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void relationshipTypes() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
-        assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
-
-        RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
-        relationshipCond.setRelationshipTypeKey("type1");
-        SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-
-        fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
-        assertEquals(
-                SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
-                fiqlExpression);
-    }
-
-    @Test
-    public void groups() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
-        assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
-
-        MembershipCond groupCond = new MembershipCond();
-        groupCond.setGroupKey(1L);
-        SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void roles() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
-        assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
-
-        RoleCond roleCond = new RoleCond();
-        roleCond.setRoleKey("User reviewer");
-        SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void resources() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
-        assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
-
-        ResourceCond resCond = new ResourceCond();
-        resCond.setResourceName("resource-ldap");
-        SearchCond simpleCond = SearchCond.getLeafCond(resCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void assignable() {
-        String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
-        assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
-
-        AssignableCond assignableCond = new AssignableCond();
-        assignableCond.setRealmFullPath("/even/two");
-        SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
-    }
-
-    @Test
-    public void type() {
-        String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
-        assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
-
-        AnyTypeCond acond = new AnyTypeCond();
-        acond.setAnyTypeName("PRINTER");
-        SearchCond simpleCond = SearchCond.getLeafCond(acond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void and() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().
-                is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
-        assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
-
-        AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond1.setSchema("fullname");
-        fullnameLeafCond1.setExpression("%o%");
-        AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond2.setSchema("fullname");
-        fullnameLeafCond2.setExpression("%i%");
-        SearchCond andCond = SearchCond.getAndCond(
-                SearchCond.getLeafCond(fullnameLeafCond1),
-                SearchCond.getLeafCond(fullnameLeafCond2));
-
-        assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
-    public void or() {
-        String fiqlExpression = new UserFiqlSearchConditionBuilder().
-                is("fullname").equalTo("*o*", "*i*", "*ini").query();
-        assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
-        fiqlExpression = new UserFiqlSearchConditionBuilder().
-                is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
-        assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
-
-        AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond1.setSchema("fullname");
-        fullnameLeafCond1.setExpression("%o%");
-        AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond2.setSchema("fullname");
-        fullnameLeafCond2.setExpression("%i%");
-        AttributeCond fullnameLeafCond3 = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond3.setSchema("fullname");
-        fullnameLeafCond3.setExpression("%ini");
-        SearchCond orCond = SearchCond.getOrCond(
-                SearchCond.getLeafCond(fullnameLeafCond1),
-                SearchCond.getOrCond(
-                        SearchCond.getLeafCond(fullnameLeafCond2),
-                        SearchCond.getLeafCond(fullnameLeafCond3)));
-
-        assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
deleted file mode 100644
index 98e8061..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
+++ /dev/null
@@ -1,58 +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.misc.security;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.junit.Test;
-
-/**
- * Test class to test all encryption algorithms.
- */
-public class EncryptorTest {
-
-    private final String password = "password";
-
-    private final Encryptor encryptor = Encryptor.getInstance();
-
-    /**
-     * Verify all algorithms.
-     */
-    @Test
-    public void testEncoder() throws Exception {
-        for (CipherAlgorithm cipherAlgorithm : CipherAlgorithm.values()) {
-            final String encPassword = encryptor.encode(password, cipherAlgorithm);
-
-            assertNotNull(encPassword);
-            assertTrue(encryptor.verify(password, cipherAlgorithm, encPassword));
-            assertFalse(encryptor.verify("pass", cipherAlgorithm, encPassword));
-
-            // check that same password encoded with BCRYPT or Salted versions results in different digest
-            if (cipherAlgorithm.equals(CipherAlgorithm.BCRYPT) || cipherAlgorithm.getAlgorithm().startsWith("S-")) {
-                final String encSamePassword = encryptor.encode(password, cipherAlgorithm);
-                assertNotNull(encSamePassword);
-                assertFalse(encSamePassword.equals(encPassword));
-                assertTrue(encryptor.verify(password, cipherAlgorithm, encSamePassword));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
deleted file mode 100644
index 536fa60..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
+++ /dev/null
@@ -1,144 +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.misc.security;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
-import org.junit.Test;
-
-public class PasswordGeneratorTest {
-
-    private final DefaultPasswordGenerator passwordGenerator = new DefaultPasswordGenerator();
-
-    private DefaultPasswordRuleConf createBaseDefaultPasswordRuleConf() {
-        DefaultPasswordRuleConf baseDefaultPasswordRuleConf = new DefaultPasswordRuleConf();
-        baseDefaultPasswordRuleConf.setAlphanumericRequired(false);
-        baseDefaultPasswordRuleConf.setDigitRequired(false);
-        baseDefaultPasswordRuleConf.setLowercaseRequired(false);
-        baseDefaultPasswordRuleConf.setMaxLength(1000);
-        baseDefaultPasswordRuleConf.setMinLength(8);
-        baseDefaultPasswordRuleConf.setMustEndWithAlpha(false);
-        baseDefaultPasswordRuleConf.setMustEndWithDigit(false);
-        baseDefaultPasswordRuleConf.setMustEndWithNonAlpha(false);
-        baseDefaultPasswordRuleConf.setMustStartWithAlpha(false);
-        baseDefaultPasswordRuleConf.setMustStartWithDigit(false);
-        baseDefaultPasswordRuleConf.setMustStartWithNonAlpha(false);
-        baseDefaultPasswordRuleConf.setMustntEndWithAlpha(false);
-        baseDefaultPasswordRuleConf.setMustntEndWithDigit(false);
-        baseDefaultPasswordRuleConf.setMustntEndWithNonAlpha(false);
-        baseDefaultPasswordRuleConf.setMustntStartWithAlpha(false);
-        baseDefaultPasswordRuleConf.setMustntStartWithDigit(false);
-        baseDefaultPasswordRuleConf.setMustntStartWithNonAlpha(false);
-        baseDefaultPasswordRuleConf.setNonAlphanumericRequired(false);
-        baseDefaultPasswordRuleConf.setUppercaseRequired(false);
-        return baseDefaultPasswordRuleConf;
-    }
-
-    @Test
-    public void startEndWithDigit() throws InvalidPasswordRuleConf {
-        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf.setMustStartWithDigit(true);
-
-        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf2.setMustEndWithDigit(true);
-
-        List<PasswordRuleConf> ruleConfs = new ArrayList<>();
-        ruleConfs.add(pwdRuleConf);
-        ruleConfs.add(pwdRuleConf2);
-        String generatedPassword = passwordGenerator.generate(ruleConfs);
-        assertTrue(Character.isDigit(generatedPassword.charAt(0)));
-        assertTrue(Character.isDigit(generatedPassword.charAt(generatedPassword.length() - 1)));
-    }
-
-    @Test
-    public void startWithDigitAndWithAlpha() throws InvalidPasswordRuleConf {
-        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf.setMustStartWithDigit(true);
-
-        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf2.setMustEndWithAlpha(true);
-
-        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
-        pwdRuleConfs.add(pwdRuleConf);
-        pwdRuleConfs.add(pwdRuleConf2);
-        String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
-        assertTrue(Character.isDigit(generatedPassword.charAt(0)));
-        assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
-    }
-
-    @Test
-    public void passwordWithNonAlpha() throws InvalidPasswordRuleConf {
-        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf.setNonAlphanumericRequired(true);
-
-        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf2.setMustEndWithAlpha(true);
-
-        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
-        pwdRuleConfs.add(pwdRuleConf);
-        pwdRuleConfs.add(pwdRuleConf2);
-        String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
-        assertTrue(PolicyPattern.NON_ALPHANUMERIC.matcher(generatedPassword).matches());
-        assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
-    }
-
-    @Test(expected = InvalidPasswordRuleConf.class)
-    public void incopatiblePolicies() throws InvalidPasswordRuleConf {
-        DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf.setMinLength(12);
-
-        DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
-        pwdRuleConf.setMaxLength(10);
-
-        List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
-        pwdRuleConfs.add(pwdRuleConf);
-        pwdRuleConfs.add(pwdRuleConf2);
-        passwordGenerator.generate(pwdRuleConfs);
-    }
-
-    @Test
-    public void issueSYNCOPE678() {
-        String password = null;
-        try {
-            password = passwordGenerator.generate(Collections.<PasswordRuleConf>emptyList());
-        } catch (InvalidPasswordRuleConf e) {
-            fail(e.getMessage());
-        }
-        assertNotNull(password);
-
-        DefaultPasswordRuleConf ppSpec = createBaseDefaultPasswordRuleConf();
-        ppSpec.setMinLength(0);
-        password = null;
-        try {
-            password = passwordGenerator.generate(Collections.<PasswordRuleConf>singletonList(ppSpec));
-        } catch (InvalidPasswordRuleConf e) {
-            fail(e.getMessage());
-        }
-        assertNotNull(password);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml
index 10745e7..b06a192 100644
--- a/core/persistence-api/pom.xml
+++ b/core/persistence-api/pom.xml
@@ -61,6 +61,19 @@ under the License.
       <artifactId>syncope-common-lib</artifactId>
       <version>${project.version}</version>
     </dependency>
+    
+    <!-- TEST -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>


[10/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
new file mode 100644
index 0000000..4b8279f
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+
+public class AuditEntry extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -2299082316063743582L;
+
+    private final String who;
+
+    private final AuditLoggerName logger;
+
+    private final Object before;
+
+    private final Object output;
+
+    private final Object[] input;
+
+    @JsonCreator
+    public AuditEntry(
+            @JsonProperty("who") final String who,
+            @JsonProperty("logger") final AuditLoggerName logger,
+            @JsonProperty("before") final Object before,
+            @JsonProperty("output") final Object output,
+            @JsonProperty("input") final Object[] input) {
+
+        super();
+        
+        this.who = who;
+        this.logger = logger;
+        this.before = before;
+        this.output = output;
+        this.input = input;
+    }
+
+    public String getWho() {
+        return who;
+    }
+
+    public AuditLoggerName getLogger() {
+        return logger;
+    }
+
+    public Object getBefore() {
+        return before;
+    }
+
+    public Object getOutput() {
+        return output;
+    }
+
+    public Object[] getInput() {
+        return input;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java
new file mode 100644
index 0000000..b692472
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.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.java;
+
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
+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;
+
+@Component
+public class AuditManagerImpl implements AuditManager {
+
+    @Autowired
+    private LoggerDAO loggerDAO;
+
+    public static String getDomainAuditLoggerName(final String domain) {
+        return LoggerType.AUDIT.getPrefix() + "." + domain;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public void audit(
+            final AuditElements.EventCategoryType type,
+            final String category,
+            final String subcategory,
+            final String event,
+            final Result result,
+            final Object before,
+            final Object output,
+            final Object... input) {
+
+        Throwable throwable = null;
+        if (output instanceof Throwable) {
+            throwable = (Throwable) output;
+        }
+
+        AuditEntry auditEntry = new AuditEntry(
+                AuthContextUtils.getUsername(),
+                new AuditLoggerName(type, category, subcategory, event, result),
+                before,
+                throwable == null ? output : throwable.getMessage(),
+                input);
+
+        org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger =
+                loggerDAO.find(auditEntry.getLogger().toLoggerName());
+        if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
+            Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(AuthContextUtils.getDomain()));
+            if (throwable == null) {
+                logger.debug(POJOHelper.serialize(auditEntry));
+            } else {
+                logger.debug(POJOHelper.serialize(auditEntry), throwable);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
index 40ff432..7e103bb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
@@ -35,7 +35,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.URIUtils;
+import org.apache.syncope.core.provisioning.api.utils.URIUtils;
 import org.identityconnectors.common.IOUtil;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.APIConfiguration;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 3454985..4e7f9e9 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
@@ -30,15 +30,15 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.misc.utils.MappingUtils;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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.identityconnectors.common.security.GuardedByteArray;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.APIConfiguration;
@@ -66,7 +66,6 @@ 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 {
 
@@ -481,7 +480,7 @@ public class ConnectorFacadeProxy implements Connector {
             }
         }, new ArrayList<SortKey>(orderBy.size())));
 
-        builder.setAttributesToGet(MappingUtils.buildOperationOptions(mapItems).getAttributesToGet());
+        builder.setAttributesToGet(MappingManagerImpl.buildOperationOptions(mapItems).getAttributesToGet());
 
         search(objectClass, filter, handler, builder.build());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 1ecc163..de2fa29 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -26,8 +26,8 @@ import java.util.Set;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index f2b489f..0cc4100 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -38,7 +38,7 @@ 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.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 831e41f..08c55a5 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -43,7 +43,7 @@ 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.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 d9028af..cd3fc5c 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
@@ -47,9 +47,9 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationException
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
index ccff795..f827f46 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.jexl3.JexlContext;
 import org.apache.commons.jexl3.MapContext;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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
new file mode 100644
index 0000000..7c97448
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -0,0 +1,847 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+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.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+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.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Schema;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+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.provisioning.api.DerAttrHandler;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.identityconnectors.framework.common.FrameworkUtil;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class MappingManagerImpl implements MappingManager {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MappingManager.class);
+
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private DerAttrHandler derAttrHandler;
+
+    @Autowired
+    private VirAttrHandler virAttrHandler;
+
+    @Autowired
+    private VirAttrCache virAttrCache;
+
+    @Autowired
+    private PasswordGenerator passwordGenerator;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
+    public static MappingItem getConnObjectKeyItem(final Provision provision) {
+        Mapping mapping = null;
+        if (provision != null) {
+            mapping = provision.getMapping();
+        }
+
+        return mapping == null
+                ? null
+                : mapping.getConnObjectKeyItem();
+    }
+
+    private static List<MappingItem> getMappingItems(final Provision provision, final MappingPurpose purpose) {
+        List<? extends MappingItem> items = Collections.<MappingItem>emptyList();
+        if (provision != null) {
+            items = provision.getMapping().getItems();
+        }
+
+        List<MappingItem> result = new ArrayList<>();
+
+        switch (purpose) {
+            case SYNCHRONIZATION:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.PROPAGATION != item.getPurpose()
+                            && MappingPurpose.NONE != item.getPurpose()) {
+
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case PROPAGATION:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
+                            && MappingPurpose.NONE != item.getPurpose()) {
+
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case BOTH:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.NONE != item.getPurpose()) {
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case NONE:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.NONE == item.getPurpose()) {
+                        result.add(item);
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    public static List<MappingItem> getBothMappingItems(final Provision provision) {
+        return getMappingItems(provision, MappingPurpose.BOTH);
+    }
+
+    public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
+        return getMappingItems(provision, MappingPurpose.PROPAGATION);
+    }
+
+    public static List<MappingItem> getSyncMappingItems(final Provision provision) {
+        return getMappingItems(provision, MappingPurpose.SYNCHRONIZATION);
+    }
+
+    /**
+     * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
+     * this case evaluate as JEXL); otherwise, take given connObjectKey.
+     *
+     * @param any given any object
+     * @param provision external resource
+     * @param connObjectKey connector object key
+     * @return the value to be propagated as __NAME__
+     */
+    public static Name evaluateNAME(final Any<?> any, final Provision provision, final String connObjectKey) {
+        if (StringUtils.isBlank(connObjectKey)) {
+            // LOG error but avoid to throw exception: leave it to the external resource
+            LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
+        }
+
+        // Evaluate connObjectKey expression
+        String connObjectLink = provision == null || provision.getMapping() == null
+                ? null
+                : provision.getMapping().getConnObjectLink();
+        String evalConnObjectLink = null;
+        if (StringUtils.isNotBlank(connObjectLink)) {
+            JexlContext jexlContext = new MapContext();
+            JexlUtils.addFieldsToContext(any, jexlContext);
+            JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+            JexlUtils.addDerAttrsToContext(any, jexlContext);
+            evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
+        }
+
+        // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
+        // otherwise evaluated connObjectLink expression is taken as Name().
+        Name name;
+        if (StringUtils.isBlank(evalConnObjectLink)) {
+            // add connObjectKey as __NAME__ attribute ...
+            LOG.debug("Add connObjectKey [{}] as __NAME__", connObjectKey);
+            name = new Name(connObjectKey);
+        } else {
+            LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
+            name = new Name(evalConnObjectLink);
+
+            // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
+            LOG.debug("connObjectKey will be used just as __UID__ attribute");
+        }
+
+        return name;
+    }
+
+    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
+        List<MappingItemTransformer> result = new ArrayList<>();
+
+        for (String className : mappingItem.getMappingItemTransformerClassNames()) {
+            try {
+                Class<?> transformerClass = ClassUtils.getClass(className);
+
+                result.add((MappingItemTransformer) ApplicationContextProvider.
+                        getBeanFactory().
+                        createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
+            } catch (Exception e) {
+                LOG.error("Could not instantiate {}, ignoring...", className, e);
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Build options for requesting all mapped connector attributes.
+     *
+     * @param mapItems mapping items
+     * @return options for requesting all mapped connector attributes
+     * @see OperationOptions
+     */
+    public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
+        OperationOptionsBuilder builder = new OperationOptionsBuilder();
+
+        Set<String> attrsToGet = new HashSet<>();
+        attrsToGet.add(Name.NAME);
+        attrsToGet.add(Uid.NAME);
+        attrsToGet.add(OperationalAttributes.ENABLE_NAME);
+
+        while (mapItems.hasNext()) {
+            MappingItem mapItem = mapItems.next();
+            if (mapItem.getPurpose() != MappingPurpose.NONE) {
+                attrsToGet.add(mapItem.getExtAttrName());
+            }
+        }
+
+        builder.setAttributesToGet(attrsToGet);
+        // -------------------------------------
+
+        return builder.build();
+    }
+
+    /**
+     * Prepare attributes for sending to a connector instance.
+     *
+     * @param any given any object
+     * @param password clear-text password
+     * @param changePwd whether password should be included for propagation attributes or not
+     * @param enable whether any object must be enabled or not
+     * @param provision provision information
+     * @return connObjectLink + prepared attributes
+     */
+    @Transactional(readOnly = true)
+    @Override
+    public Pair<String, Set<Attribute>> prepareAttrs(
+            final Any<?> any,
+            final String password,
+            final boolean changePwd,
+            final Boolean enable,
+            final Provision provision) {
+
+        LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
+                any, provision, any.getPlainAttrs());
+
+        Set<Attribute> attributes = new HashSet<>();
+        String connObjectKey = null;
+
+        for (MappingItem mappingItem : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+            LOG.debug("Processing schema {}", mappingItem.getIntAttrName());
+
+            try {
+                Pair<String, Attribute> preparedAttr = prepareAttr(provision, mappingItem, any, password);
+
+                if (preparedAttr != null && preparedAttr.getKey() != null) {
+                    connObjectKey = preparedAttr.getKey();
+                }
+
+                if (preparedAttr != null && preparedAttr.getValue() != null) {
+                    Attribute alreadyAdded = AttributeUtil.find(preparedAttr.getValue().getName(), attributes);
+
+                    if (alreadyAdded == null) {
+                        attributes.add(preparedAttr.getValue());
+                    } else {
+                        attributes.remove(alreadyAdded);
+
+                        Set<Object> values = new HashSet<>(alreadyAdded.getValue());
+                        values.addAll(preparedAttr.getValue().getValue());
+
+                        attributes.add(AttributeBuilder.build(preparedAttr.getValue().getName(), values));
+                    }
+                }
+            } catch (Exception e) {
+                LOG.debug("Attribute '{}' processing failed", mappingItem.getIntAttrName(), e);
+            }
+        }
+
+        Attribute connObjectKeyExtAttr =
+                AttributeUtil.find(getConnObjectKeyItem(provision).getExtAttrName(), attributes);
+        if (connObjectKeyExtAttr != null) {
+            attributes.remove(connObjectKeyExtAttr);
+            attributes.add(AttributeBuilder.build(getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
+        }
+        attributes.add(evaluateNAME(any, provision, connObjectKey));
+
+        if (enable != null) {
+            attributes.add(AttributeBuilder.buildEnabled(enable));
+        }
+        if (!changePwd) {
+            Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes);
+            if (pwdAttr != null) {
+                attributes.remove(pwdAttr);
+            }
+        }
+
+        return new ImmutablePair<>(connObjectKey, attributes);
+    }
+
+    /**
+     * Prepare an attribute to be sent to a connector instance.
+     *
+     * @param provision external resource
+     * @param mapItem mapping item for the given attribute
+     * @param any any object
+     * @param password clear-text password
+     * @return connObjectKey + prepared attribute
+     */
+    private Pair<String, Attribute> prepareAttr(
+            final Provision provision, final MappingItem mapItem, final Any<?> any, final String password) {
+
+        List<Any<?>> anys = new ArrayList<>();
+
+        switch (mapItem.getIntMappingType().getAnyTypeKind()) {
+            case USER:
+                if (any instanceof User) {
+                    anys.add(any);
+                }
+                break;
+
+            case GROUP:
+                if (any instanceof User) {
+                    for (Group group : userDAO.findAllGroups((User) any)) {
+                        anys.add(group);
+                    }
+                } else if (any instanceof Group) {
+                    anys.add(any);
+                }
+                break;
+
+            case ANY_OBJECT:
+                if (any instanceof AnyObject) {
+                    anys.add(any);
+                }
+                break;
+
+            default:
+        }
+
+        Schema schema = null;
+        boolean readOnlyVirSchema = false;
+        AttrSchemaType schemaType;
+        Pair<String, Attribute> result;
+
+        switch (mapItem.getIntMappingType()) {
+            case UserPlainSchema:
+            case GroupPlainSchema:
+            case AnyObjectPlainSchema:
+                schema = plainSchemaDAO.find(mapItem.getIntAttrName());
+                schemaType = schema == null ? AttrSchemaType.String : schema.getType();
+                break;
+
+            case UserVirtualSchema:
+            case GroupVirtualSchema:
+            case AnyObjectVirtualSchema:
+                schema = virSchemaDAO.find(mapItem.getIntAttrName());
+                readOnlyVirSchema = (schema != null && schema.isReadonly());
+                schemaType = AttrSchemaType.String;
+                break;
+
+            default:
+                schemaType = AttrSchemaType.String;
+        }
+
+        String extAttrName = mapItem.getExtAttrName();
+
+        List<PlainAttrValue> values = getIntValues(provision, mapItem, anys);
+
+        LOG.debug("Define mapping for: "
+                + "\n* ExtAttrName " + extAttrName
+                + "\n* is connObjectKey " + mapItem.isConnObjectKey()
+                + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
+                + "\n* mandatory condition " + mapItem.getMandatoryCondition()
+                + "\n* Schema " + mapItem.getIntAttrName()
+                + "\n* IntMappingType " + mapItem.getIntMappingType().toString()
+                + "\n* ClassType " + schemaType.getType().getName()
+                + "\n* Values " + values);
+
+        if (readOnlyVirSchema) {
+            result = null;
+        } else {
+            List<Object> objValues = new ArrayList<>();
+
+            for (PlainAttrValue value : values) {
+                if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) {
+                    objValues.add(value.getValue());
+                } else {
+                    objValues.add(value.getValueAsString());
+                }
+            }
+
+            if (mapItem.isConnObjectKey()) {
+                result = new ImmutablePair<>(objValues.iterator().next().toString(), null);
+            } else if (mapItem.isPassword() && any instanceof User) {
+                String passwordAttrValue = password;
+                if (StringUtils.isBlank(passwordAttrValue)) {
+                    User user = (User) any;
+                    if (user.canDecodePassword()) {
+                        try {
+                            passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
+                        } catch (Exception e) {
+                            LOG.error("Could not decode password for {}", user, e);
+                        }
+                    } else if (provision.getResource().isRandomPwdIfNotProvided()) {
+                        try {
+                            passwordAttrValue = passwordGenerator.generate(user);
+                        } catch (InvalidPasswordRuleConf e) {
+                            LOG.error("Could not generate policy-compliant random password for {}", user, e);
+                        }
+                    }
+                }
+
+                if (passwordAttrValue == null) {
+                    result = null;
+                } else {
+                    result = new ImmutablePair<>(
+                            null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
+                }
+            } else if ((schema != null && schema.isMultivalue())
+                    || anyUtilsFactory.getInstance(any).getAnyTypeKind()
+                    != mapItem.getIntMappingType().getAnyTypeKind()) {
+
+                result = new ImmutablePair<>(
+                        null, AttributeBuilder.build(extAttrName, objValues));
+            } else {
+                result = new ImmutablePair<>(
+                        null, objValues.isEmpty()
+                                ? AttributeBuilder.build(extAttrName)
+                                : AttributeBuilder.build(extAttrName, objValues.iterator().next()));
+            }
+        }
+
+        return result;
+    }
+
+    private String getGroupOwnerValue(final Provision provision, final Any<?> any) {
+        Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision), any, null);
+        String connObjectKey = preparedAttr.getKey();
+
+        return evaluateNAME(any, provision, connObjectKey).getNameValue();
+    }
+
+    /**
+     * Get attribute values for the given {@link MappingItem} and any objects.
+     *
+     * @param provision provision information
+     * @param mappingItem mapping item
+     * @param anys any objects
+     * @return attribute values.
+     */
+    @Transactional(readOnly = true)
+    @Override
+    public List<PlainAttrValue> getIntValues(final Provision provision,
+            final MappingItem mappingItem, final List<Any<?>> anys) {
+
+        LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
+
+        boolean transform = true;
+
+        List<PlainAttrValue> values = new ArrayList<>();
+        switch (mappingItem.getIntMappingType()) {
+            case UserPlainSchema:
+            case GroupPlainSchema:
+            case AnyObjectPlainSchema:
+                for (Any<?> any : anys) {
+                    PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
+                    if (attr != null) {
+                        if (attr.getUniqueValue() != null) {
+                            PlainAttrUniqueValue value = SerializationUtils.clone(attr.getUniqueValue());
+                            value.setAttr(null);
+                            values.add(value);
+                        } else if (attr.getValues() != null) {
+                            for (PlainAttrValue value : attr.getValues()) {
+                                PlainAttrValue shadow = SerializationUtils.clone(value);
+                                shadow.setAttr(null);
+                                values.add(shadow);
+                            }
+                        }
+                    }
+
+                    LOG.debug("Retrieved attribute {}"
+                            + "\n* IntAttrName {}"
+                            + "\n* IntMappingType {}"
+                            + "\n* Attribute values {}",
+                            attr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
+                }
+
+                break;
+
+            case UserDerivedSchema:
+            case GroupDerivedSchema:
+            case AnyObjectDerivedSchema:
+                DerSchema derSchema = derSchemaDAO.find(mappingItem.getIntAttrName());
+                if (derSchema != null) {
+                    for (Any<?> any : anys) {
+                        String value = derAttrHandler.getValue(any, derSchema);
+                        if (value != null) {
+                            AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                            attrValue.setStringValue(value);
+                            values.add(attrValue);
+
+                            LOG.debug("Retrieved values for {}"
+                                    + "\n* IntAttrName {}"
+                                    + "\n* IntMappingType {}"
+                                    + "\n* Attribute values {}",
+                                    derSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
+                                    values);
+                        }
+                    }
+                }
+                break;
+
+            case UserVirtualSchema:
+            case GroupVirtualSchema:
+            case AnyObjectVirtualSchema:
+                // virtual attributes don't get transformed
+                transform = false;
+
+                VirSchema virSchema = virSchemaDAO.find(mappingItem.getIntAttrName());
+                if (virSchema != null) {
+                    for (Any<?> any : anys) {
+                        LOG.debug("Expire entry cache {}-{}", any.getKey(), mappingItem.getIntAttrName());
+                        virAttrCache.expire(any.getType().getKey(), any.getKey(), mappingItem.getIntAttrName());
+
+                        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                        for (String value : virAttrHandler.getValues(any, virSchema)) {
+                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                            attrValue.setStringValue(value);
+                            values.add(attrValue);
+                        }
+
+                        LOG.debug("Retrieved values for {}"
+                                + "\n* IntAttrName {}"
+                                + "\n* IntMappingType {}"
+                                + "\n* Attribute values {}",
+                                virSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
+                                values);
+                    }
+                }
+                break;
+
+            case UserKey:
+            case GroupKey:
+            case AnyObjectKey:
+                for (Any<?> any : anys) {
+                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                    PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                    attrValue.setStringValue(any.getKey().toString());
+                    values.add(attrValue);
+                }
+                break;
+
+            case Username:
+                for (Any<?> any : anys) {
+                    if (any instanceof User) {
+                        UPlainAttrValue attrValue = entityFactory.newEntity(UPlainAttrValue.class);
+                        attrValue.setStringValue(((User) any).getUsername());
+                        values.add(attrValue);
+                    }
+                }
+                break;
+
+            case GroupName:
+                for (Any<?> any : anys) {
+                    if (any instanceof Group) {
+                        GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
+                        attrValue.setStringValue(((Group) any).getName());
+                        values.add(attrValue);
+                    }
+                }
+                break;
+
+            case GroupOwnerSchema:
+                Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
+                        ? provision.getMapping()
+                        : null;
+                Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
+                        ? provision.getMapping()
+                        : null;
+
+                for (Any<?> any : anys) {
+                    if (any instanceof Group) {
+                        Group group = (Group) any;
+                        String groupOwnerValue = null;
+                        if (group.getUserOwner() != null && uMapping != null) {
+                            groupOwnerValue = getGroupOwnerValue(provision, group.getUserOwner());
+                        }
+                        if (group.getGroupOwner() != null && gMapping != null) {
+                            groupOwnerValue = getGroupOwnerValue(provision, group.getGroupOwner());
+                        }
+
+                        if (StringUtils.isNotBlank(groupOwnerValue)) {
+                            GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
+                            attrValue.setStringValue(groupOwnerValue);
+                            values.add(attrValue);
+                        }
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        LOG.debug("Values for propagation: {}", values);
+
+        List<PlainAttrValue> transformed = values;
+        if (transform) {
+            for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
+                transformed = transformer.beforePropagation(transformed);
+            }
+            LOG.debug("Transformed values for propagation: {}", values);
+        } else {
+            LOG.debug("No transformation occurred");
+        }
+
+        return transformed;
+    }
+
+    /**
+     * Get connObjectKey internal value.
+     *
+     * @param any any object
+     * @param provision provision information
+     * @return connObjectKey internal value
+     */
+    @Transactional(readOnly = true)
+    @Override
+    public String getConnObjectKeyValue(final Any<?> any, final Provision provision) {
+        List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
+                Collections.<Any<?>>singletonList(any));
+        return values == null || values.isEmpty()
+                ? null
+                : values.get(0).getValueAsString();
+    }
+
+    /**
+     * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
+     * connector.
+     *
+     * @param <T> any object
+     * @param mappingItem mapping item
+     * @param attr attribute received from connector
+     * @param anyTO any object
+     * @param anyUtils any utils
+     */
+    @Transactional(readOnly = true)
+    @Override
+    public <T extends AnyTO> void setIntValues(
+            final MappingItem mappingItem, final Attribute attr, final T anyTO, final AnyUtils anyUtils) {
+
+        List<Object> values = null;
+        if (attr != null) {
+            values = attr.getValue();
+            for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
+                values = transformer.beforeSync(values);
+            }
+        }
+        values = ListUtils.emptyIfNull(values);
+
+        switch (mappingItem.getIntMappingType()) {
+            case UserKey:
+            case GroupKey:
+            case AnyObjectKey:
+                break;
+
+            case Password:
+                if (anyTO instanceof UserTO && !values.isEmpty()) {
+                    ((UserTO) anyTO).setPassword(ConnObjectUtils.getPassword(values.get(0)));
+                }
+                break;
+
+            case Username:
+                if (anyTO instanceof UserTO) {
+                    ((UserTO) anyTO).setUsername(values.isEmpty() || values.get(0) == null
+                            ? null
+                            : values.get(0).toString());
+                }
+                break;
+
+            case GroupName:
+                if (anyTO instanceof GroupTO) {
+                    ((GroupTO) anyTO).setName(values.isEmpty() || values.get(0) == null
+                            ? null
+                            : values.get(0).toString());
+                }
+                break;
+
+            case GroupOwnerSchema:
+                if (anyTO instanceof GroupTO && attr != null) {
+                    // using a special attribute (with schema "", that will be ignored) for carrying the
+                    // GroupOwnerSchema value
+                    AttrTO attrTO = new AttrTO();
+                    attrTO.setSchema(StringUtils.EMPTY);
+                    if (values.isEmpty() || values.get(0) == null) {
+                        attrTO.getValues().add(StringUtils.EMPTY);
+                    } else {
+                        attrTO.getValues().add(values.get(0).toString());
+                    }
+
+                    ((GroupTO) anyTO).getPlainAttrs().add(attrTO);
+                }
+                break;
+
+            case UserPlainSchema:
+            case GroupPlainSchema:
+            case AnyObjectPlainSchema:
+                AttrTO attrTO = new AttrTO();
+                attrTO.setSchema(mappingItem.getIntAttrName());
+
+                PlainSchema schema = plainSchemaDAO.find(mappingItem.getIntAttrName());
+
+                for (Object value : values) {
+                    AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
+                    if (value != null) {
+                        PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                        switch (schemaType) {
+                            case String:
+                                attrValue.setStringValue(value.toString());
+                                break;
+
+                            case Binary:
+                                attrValue.setBinaryValue((byte[]) value);
+                                break;
+
+                            default:
+                                try {
+                                    attrValue.parseValue(schema, value.toString());
+                                } catch (ParsingValidationException e) {
+                                    LOG.error("While parsing provided value {}", value, e);
+                                    attrValue.setStringValue(value.toString());
+                                    schemaType = AttrSchemaType.String;
+                                }
+                                break;
+                        }
+                        attrTO.getValues().add(attrValue.getValueAsString(schemaType));
+                    }
+                }
+
+                anyTO.getPlainAttrs().add(attrTO);
+                break;
+
+            case UserDerivedSchema:
+            case GroupDerivedSchema:
+            case AnyObjectDerivedSchema:
+                attrTO = new AttrTO();
+                attrTO.setSchema(mappingItem.getIntAttrName());
+                anyTO.getDerAttrs().add(attrTO);
+                break;
+
+            case UserVirtualSchema:
+            case GroupVirtualSchema:
+            case AnyObjectVirtualSchema:
+                attrTO = new AttrTO();
+                attrTO.setSchema(mappingItem.getIntAttrName());
+
+                // virtual attributes don't get transformed, iterate over original attr.getValue()
+                for (Object value : (attr == null || attr.getValue() == null)
+                        ? Collections.emptyList() : attr.getValue()) {
+
+                    if (value != null) {
+                        attrTO.getValues().add(value.toString());
+                    }
+                }
+
+                anyTO.getVirAttrs().add(attrTO);
+                break;
+
+            default:
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index ca50635..b65cc79 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -27,7 +27,6 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -36,6 +35,7 @@ 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.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
@@ -60,7 +60,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
     private VirAttrCache virAttrCache;
 
     @Autowired
-    private MappingUtils mappingUtils;
+    private MappingManager mappingManager;
 
     @Autowired
     private AnyUtilsFactory anyUtilsFactory;
@@ -97,9 +97,9 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
         for (Map.Entry<Provision, Set<VirSchema>> entry : toRead.entrySet()) {
             LOG.debug("About to read from {}: {}", entry.getKey(), entry.getValue());
 
-            String connObjectKey = MappingUtils.getConnObjectKeyItem(entry.getKey()) == null
+            String connObjectKey = MappingManagerImpl.getConnObjectKeyItem(entry.getKey()) == null
                     ? null
-                    : mappingUtils.getConnObjectKeyValue(any, entry.getKey());
+                    : mappingManager.getConnObjectKeyValue(any, entry.getKey());
             if (StringUtils.isBlank(connObjectKey)) {
                 LOG.error("No ConnObjectKey found for {}, ignoring...", entry.getKey());
             } else {
@@ -110,10 +110,9 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
 
                 Connector connector = connFactory.getConnector(entry.getKey().getResource());
                 try {
-                    ConnectorObject connectorObject = connector.getObject(
-                            entry.getKey().getObjectClass(),
+                    ConnectorObject connectorObject = connector.getObject(entry.getKey().getObjectClass(),
                             new Uid(connObjectKey),
-                            MappingUtils.buildOperationOptions(linkingMappingItems.iterator()));
+                            MappingManagerImpl.buildOperationOptions(linkingMappingItems.iterator()));
 
                     if (connectorObject == null) {
                         LOG.debug("No read from {} about {}", entry.getKey(), connObjectKey);

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 3d96cfc..56e0d71 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -59,10 +59,10 @@ 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.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 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.AnyTypeClassDAO;
@@ -83,6 +83,7 @@ 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.user.User;
 import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -155,7 +156,7 @@ abstract class AbstractAnyDataBinder {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected MappingUtils mappingUtils;
+    protected MappingManager mappingManager;
 
     protected void setRealm(final Any<?> any, final AnyPatch anyPatch) {
         if (anyPatch.getRealm() != null && StringUtils.isNotBlank(anyPatch.getRealm().getValue())) {
@@ -232,7 +233,7 @@ abstract class AbstractAnyDataBinder {
                         && (item.getPurpose() == MappingPurpose.PROPAGATION
                         || item.getPurpose() == MappingPurpose.BOTH)) {
 
-                    List<PlainAttrValue> values = mappingUtils.getIntValues(
+                    List<PlainAttrValue> values = mappingManager.getIntValues(
                             provision, item, Collections.<Any<?>>singletonList(any));
                     if (values.isEmpty() && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
                         missingAttrNames.add(item.getIntAttrName());
@@ -351,7 +352,8 @@ abstract class AbstractAnyDataBinder {
         }
 
         for (ExternalResource resource : resources) {
-            for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(resource.getProvision(any.getType()))) {
+            for (MappingItem mapItem : MappingManagerImpl.getPropagationMappingItems(resource.
+                    getProvision(any.getType()))) {
                 if (schema.getKey().equals(mapItem.getIntAttrName())
                         && mapItem.getIntMappingType() == anyUtils.plainIntMappingType()) {
 
@@ -574,14 +576,14 @@ abstract class AbstractAnyDataBinder {
         for (ExternalResource resource : iterable) {
             Provision provision = resource.getProvision(any.getType());
             if (provision != null && provision.getMapping() != null) {
-                MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+                MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
                 if (connObjectKeyItem == null) {
                     throw new NotFoundException(
                             "ConnObjectKey mapping for " + any.getType().getKey() + " " + any.getKey()
                             + " on resource '" + resource.getKey() + "'");
                 }
 
-                String connObjectKey = mappingUtils.getConnObjectKeyValue(any, provision);
+                String connObjectKey = mappingManager.getConnObjectKeyValue(any, provision);
                 if (connObjectKey != null) {
                     connObjectKeys.put(resource.getKey(), connObjectKey);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 1c889f6..7d12f6f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -40,8 +40,8 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 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.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 00935f7..5d277b3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -27,7 +27,7 @@ import org.apache.commons.jexl3.MapContext;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index d4a6b08..9129900 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -33,11 +33,11 @@ import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
 import org.identityconnectors.framework.api.ConfigurationProperties;
 import org.identityconnectors.framework.api.ConfigurationProperty;
 import org.identityconnectors.framework.impl.api.ConfigurationPropertyImpl;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index a51729b..ba94507 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyType;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
index 1c11b36..eb0c328 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyAbout;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 c1c3254..42de46f 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
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 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.dao.RealmDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
index 1bf5dc9..7b12665 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
@@ -31,7 +31,7 @@ import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
 import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.ReportTemplateDAO;
 import org.apache.syncope.core.persistence.api.entity.ReportTemplate;
 import org.quartz.Scheduler;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 5f0decf..97aa6f2 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
@@ -42,10 +42,10 @@ 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.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
index 1bef90e..a95b60d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
@@ -23,7 +23,7 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index dc8a957..ac28f14 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -31,8 +31,8 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
index 34523f2..ed971eb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
@@ -22,7 +22,7 @@ import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder;
 import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/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 fb7b268..e262521 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
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.JobType;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
@@ -51,7 +51,7 @@ 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;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -59,8 +59,8 @@ 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.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index 36b3b77..94686aa 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -53,10 +53,10 @@ import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
new file mode 100644
index 0000000..aec38b8
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jexl;
+
+import org.apache.commons.jexl3.internal.introspection.Uberspect;
+import org.apache.commons.jexl3.introspection.JexlMethod;
+import org.apache.commons.jexl3.introspection.JexlPropertyGet;
+
+class ClassFreeUberspect extends Uberspect {
+
+    ClassFreeUberspect() {
+        super(null, null);
+    }
+
+    @Override
+    public JexlPropertyGet getPropertyGet(final Object obj, final Object identifier) {
+        return "class".equals(identifier) ? null : super.getPropertyGet(obj, identifier);
+    }
+
+    @Override
+    public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
+        return "getClass".equals(method) ? null : super.getMethod(obj, method, args);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
new file mode 100644
index 0000000..037113e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.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.java.jexl;
+
+/**
+ * A class loader that will throw {@link ClassNotFoundException} for every class name.
+ */
+class EmptyClassLoader extends ClassLoader {
+
+    @Override
+    public Class<?> loadClass(final String name) throws ClassNotFoundException {
+        throw new ClassNotFoundException("This classloader won't attemp to load " + name);
+    }
+
+    @Override
+    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        throw new ClassNotFoundException("This classloader won't attemp to load " + name);
+    }
+
+}


[07/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
deleted file mode 100644
index 9c6294a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.misc.AuditManager;
-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.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
deleted file mode 100644
index 3f08704..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
deleted file mode 100644
index 14ba28e..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-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.sync.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 : MappingUtils.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
-                    : MappingUtils.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
deleted file mode 100644
index ba70634..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.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.sync.AnyObjectPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/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
deleted file mode 100644
index cf0f020..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
+++ /dev/null
@@ -1,251 +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.sync;
-
-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.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.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.sync.AnyObjectSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.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.sync.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,
-                                    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 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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
deleted file mode 100644
index 17749d1..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ /dev/null
@@ -1,318 +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.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.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.sync.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);
-            }
-        },
-                MappingUtils.buildOperationOptions(MappingUtils.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 = MappingUtils.getConnObjectKeyItem(provision);
-
-        String transfUid = uid;
-        for (MappingItemTransformer transformer : MappingUtils.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
deleted file mode 100644
index 03865d7..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
deleted file mode 100644
index 2a222d0..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.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);
-    }
-}


[08/17] syncope git commit: Further refactoring as per SYNCOPE-620

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
deleted file mode 100644
index 2c5bbb9..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.SyncActions;
-import org.apache.syncope.core.misc.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.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
deleted file mode 100644
index 4e6f2eb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.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.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.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
deleted file mode 100644
index f9546cc..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
deleted file mode 100644
index d194a25..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.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.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler implements AnyObjectSyncResultHandler {
-
-    @Override
-    protected AnyUtils getAnyUtils() {
-        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
-    }
-
-    @Override
-    protected String getName(final AnyTO anyTO) {
-        return StringUtils.EMPTY;
-    }
-
-    @Override
-    protected 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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
deleted file mode 100644
index 6e8af59..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
deleted file mode 100644
index a005493..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/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
deleted file mode 100644
index 2c75928..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.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/28569df5/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
deleted file mode 100644
index 9045e2a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
deleted file mode 100644
index 571fc47..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.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/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
deleted file mode 100644
index c3c63fb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/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.sync;
-
-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.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.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;
-    }
-
-}