You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/10/29 10:40:02 UTC

[01/10] syncope git commit: [SYNCOPE-712] Searching roles by parent

Repository: syncope
Updated Branches:
  refs/heads/master 1ebc0bcd0 -> e486aaf3a


[SYNCOPE-712] Searching roles by parent


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

Branch: refs/heads/master
Commit: fb577531bd39cb80b8ab81eefc344e04e5672af4
Parents: 03c9bc2
Author: Marco Di Sabatino Di Diodoro <md...@apache.org>
Authored: Mon Oct 19 16:23:08 2015 +0200
Committer: Marco Di Sabatino Di Diodoro <md...@apache.org>
Committed: Mon Oct 19 16:23:08 2015 +0200

----------------------------------------------------------------------
 .../core/persistence/dao/impl/SubjectSearchDAOImpl.java  | 11 ++++++++---
 .../apache/syncope/core/services/RoleServiceImpl.java    | 11 ++++++++---
 .../org/apache/syncope/core/rest/SearchTestITCase.java   |  9 +++++++++
 3 files changed, 25 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/fb577531/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SubjectSearchDAOImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SubjectSearchDAOImpl.java b/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SubjectSearchDAOImpl.java
index 5550690..ebac233 100644
--- a/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SubjectSearchDAOImpl.java
+++ b/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SubjectSearchDAOImpl.java
@@ -31,6 +31,7 @@ import javax.persistence.TemporalType;
 import javax.validation.ValidationException;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.types.AttributeSchemaType;
 import org.apache.syncope.common.types.SubjectType;
@@ -59,6 +60,8 @@ public class SubjectSearchDAOImpl extends AbstractDAOImpl implements SubjectSear
 
     private static final String EMPTY_ATTR_QUERY = "SELECT subject_id FROM user_search_attr WHERE 1=2";
 
+    private static final String[] SUBJECT_FIELDS = new String[] { "parent", "userOwner", "roleOwner" };
+
     @Autowired
     private UserDAO userDAO;
 
@@ -645,7 +648,10 @@ public class SubjectSearchDAOImpl extends AbstractDAOImpl implements SubjectSear
 
         final AttributableUtil attrUtil = AttributableUtil.getInstance(type.asAttributableType());
 
-        Field subjectField = ReflectionUtils.findField(attrUtil.attributableClass(), cond.getSchema());
+        int subjFieldIdx = ArrayUtils.indexOf(SUBJECT_FIELDS, StringUtils.substringBeforeLast(cond.getSchema(), "_"));
+        Field subjectField = ReflectionUtils.findField(
+                attrUtil.attributableClass(),
+                subjFieldIdx == -1 ? cond.getSchema() : SUBJECT_FIELDS[subjFieldIdx]);
         if (subjectField == null) {
             LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
             return EMPTY_ATTR_QUERY;
@@ -682,8 +688,7 @@ public class SubjectSearchDAOImpl extends AbstractDAOImpl implements SubjectSear
             if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getId") != null) {
                 cond.setSchema(cond.getSchema() + "_id");
                 schema.setType(AttributeSchemaType.Long);
-            }
-            if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getName") != null) {
+            } else if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getName") != null) {
                 cond.setSchema(cond.getSchema() + "_name");
                 schema.setType(AttributeSchemaType.String);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/fb577531/core/src/main/java/org/apache/syncope/core/services/RoleServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/services/RoleServiceImpl.java b/core/src/main/java/org/apache/syncope/core/services/RoleServiceImpl.java
index 04d48ea..639ab2e 100644
--- a/core/src/main/java/org/apache/syncope/core/services/RoleServiceImpl.java
+++ b/core/src/main/java/org/apache/syncope/core/services/RoleServiceImpl.java
@@ -33,7 +33,6 @@ import org.apache.syncope.common.types.ResourceAssociationActionType;
 import org.apache.syncope.common.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.util.CollectionWrapper;
 import org.apache.syncope.core.persistence.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.dao.search.SearchCond;
 import org.apache.syncope.core.rest.controller.RoleController;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -117,10 +116,16 @@ public class RoleServiceImpl extends AbstractServiceImpl implements RoleService
     public PagedResult<RoleTO> search(
             final String fiql, final Integer page, final Integer size, final String orderBy, final boolean details) {
 
-        SearchCond cond = getSearchCond(fiql);
         List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
         return buildPagedResult(
-                controller.search(cond, page, size, orderByClauses, details), page, size, controller.searchCount(cond));
+                controller.search(getSearchCond(fiql),
+                        page,
+                        size,
+                        orderByClauses,
+                        details),
+                page,
+                size,
+                controller.searchCount(getSearchCond(fiql)));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/fb577531/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java
index 27751c5..406d9b6 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/SearchTestITCase.java
@@ -178,4 +178,13 @@ public class SearchTestITCase extends AbstractTest {
             assertNotNull(user);
         }
     }
+
+    @Test
+    public void issueSYNCOPE712() {
+        final PagedResult<RoleTO> matchingRoles = roleService.search(
+                SyncopeClient.getRoleSearchConditionBuilder().is("parent").equalTo(1L).query());
+
+        assertNotNull(matchingRoles);
+        assertFalse(matchingRoles.getResult().isEmpty());
+    }
 }


[04/10] syncope git commit: Upgrading Tomcat

Posted by il...@apache.org.
Upgrading Tomcat


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

Branch: refs/heads/master
Commit: d2f57abd7840fe912f5a4cb07a6a78455b78d6da
Parents: 4dd3455
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Oct 21 12:22:58 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Oct 21 12:22:58 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d2f57abd/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7c0e39a..3b74d7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -375,7 +375,7 @@ under the License.
     
     <httpclient.version>4.3.6</httpclient.version>
 
-    <tomcat.version>7.0.64</tomcat.version>
+    <tomcat.version>7.0.65</tomcat.version>
 
     <jasypt.version>1.9.2</jasypt.version>
  


[09/10] syncope git commit: [SYNCOPE-141] Preliminary changes

Posted by il...@apache.org.
[SYNCOPE-141] Preliminary changes


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

Branch: refs/heads/master
Commit: 0211410bac90d6d7b48bbeaa20675dadfe70b255
Parents: 1ebc0bc
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Oct 26 14:43:22 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Oct 29 10:21:20 2015 +0100

----------------------------------------------------------------------
 .../syncope/core/logic/AbstractAnyLogic.java    |   4 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   2 +-
 .../syncope/core/logic/ResourceLogic.java       |   4 +-
 .../notification/NotificationJobDelegate.java   |   2 +-
 .../core/logic/report/ReportJobDelegate.java    |   2 +-
 .../core/logic/report/StaticReportlet.java      |   2 +-
 .../core/logic/report/UserReportlet.java        |   2 +-
 .../syncope/core/misc/ConnObjectUtils.java      | 259 ------
 .../syncope/core/misc/ExceptionUtils2.java      |  47 --
 .../apache/syncope/core/misc/FormatUtils.java   | 117 ---
 .../apache/syncope/core/misc/MappingUtils.java  | 831 -------------------
 .../apache/syncope/core/misc/RealmUtils.java    |  61 --
 .../apache/syncope/core/misc/TemplateUtils.java | 223 -----
 .../syncope/core/misc/jexl/JexlUtils.java       |   2 +-
 .../core/misc/security/AuthDataAccessor.java    |   4 +-
 .../misc/security/SyncopeGrantedAuthority.java  |   2 +-
 .../core/misc/utils/ConnObjectUtils.java        | 259 ++++++
 .../core/misc/utils/ExceptionUtils2.java        |  47 ++
 .../syncope/core/misc/utils/FormatUtils.java    | 117 +++
 .../syncope/core/misc/utils/MappingUtils.java   | 831 +++++++++++++++++++
 .../syncope/core/misc/utils/RealmUtils.java     |  61 ++
 .../syncope/core/misc/utils/TemplateUtils.java  | 223 +++++
 core/misc/src/main/resources/utilsContext.xml   |  32 +
 .../jpa/content/ContentLoaderHandler.java       |   2 +-
 .../jpa/content/XMLContentExporter.java         |   2 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |   2 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   2 +-
 .../jpa/entity/AbstractPlainAttrValue.java      |   2 +-
 .../provisioning/java/ConnectorFacadeProxy.java |   2 +-
 .../provisioning/java/VirAttrHandlerImpl.java   |   2 +-
 .../java/data/AbstractAnyDataBinder.java        |   4 +-
 .../java/data/RealmDataBinderImpl.java          |   2 +-
 .../java/data/TaskDataBinderImpl.java           |   2 +-
 .../java/job/AbstractSchedTaskJobDelegate.java  |   2 +-
 .../core/provisioning/java/job/TaskJob.java     |   2 +-
 .../AbstractPropagationTaskExecutor.java        |   6 +-
 .../propagation/DefaultPropagationReporter.java |   2 +-
 .../PriorityPropagationTaskExecutor.java        |  13 +-
 .../propagation/PropagationManagerImpl.java     |   4 +-
 .../java/sync/AbstractPushResultHandler.java    |   2 +-
 .../java/sync/AbstractSyncopeResultHandler.java |   2 +-
 .../sync/PlainAttrsSyncCorrelationRule.java     |   4 +-
 .../provisioning/java/sync/SyncJobDelegate.java |   2 +-
 .../core/provisioning/java/sync/SyncUtils.java  |   2 +-
 .../src/main/resources/provisioning.properties  |   3 +
 .../src/main/resources/provisioningContext.xml  |  12 +-
 .../core/provisioning/java/AbstractTest.java    |   1 +
 .../core/provisioning/java/MappingTest.java     |   2 +-
 .../rest/cxf/ThreadLocalCleanupListener.java    |   2 +-
 .../src/main/resources/provisioning.properties  |   4 +
 fit/core-reference/pom.xml                      |   1 +
 .../main/resources/all/provisioning.properties  |   4 +
 .../resources/mariadb/provisioning.properties   |   5 +-
 .../resources/mysql/provisioning.properties     |   5 +-
 .../resources/oracle/provisioning.properties    |   5 +-
 .../resources/postgres/provisioning.properties  |   5 +-
 .../src/main/resources/provisioning.properties  |   5 +-
 .../resources/sqlserver/provisioning.properties |   5 +-
 58 files changed, 1660 insertions(+), 1596 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 9a796ef..111f0ba 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
@@ -34,8 +34,8 @@ import org.apache.syncope.common.lib.to.GroupTO;
 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.RealmUtils;
-import org.apache.syncope.core.misc.TemplateUtils;
+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.persistence.api.dao.AnyTypeDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 2a2e0a3..a563088 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
@@ -42,7 +42,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.misc.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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 a6a2610..c392058 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.ConnObjectUtils;
-import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.misc.utils.ConnObjectUtils;
+import org.apache.syncope.core.misc.utils.MappingUtils;
 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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 763bab5..df8c629 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
@@ -26,7 +26,7 @@ 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.ExceptionUtils2;
+import org.apache.syncope.core.misc.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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 2b63d1b..9d764ba 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,7 +33,7 @@ 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.ExceptionUtils2;
+import org.apache.syncope.core.misc.utils.ExceptionUtils2;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.dao.ReportDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 0e785b1..37e896b 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.FormatUtils;
+import org.apache.syncope.core.misc.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/0211410b/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 3eb96b3..2523e8f 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
@@ -38,7 +38,7 @@ 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.FormatUtils;
+import org.apache.syncope.core.misc.utils.FormatUtils;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.URelationship;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
deleted file mode 100644
index f78cc31..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
+++ /dev/null
@@ -1,259 +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.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.common.lib.types.AnyTypeKind;
-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 (AnyTypeKind.USER == anyUtils.getAnyTypeKind()) {
-            // 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);
-        } else if (AnyTypeKind.GROUP == anyUtils.getAnyTypeKind()) {
-            return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
-        } else if (AnyTypeKind.ANY_OBJECT == anyUtils.getAnyTypeKind()) {
-            return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
-        }
-
-        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();
-
-        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/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/ExceptionUtils2.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/ExceptionUtils2.java b/core/misc/src/main/java/org/apache/syncope/core/misc/ExceptionUtils2.java
deleted file mode 100644
index a4f04a6..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/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;
-
-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/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
deleted file mode 100644
index 0b06906..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
+++ /dev/null
@@ -1,117 +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.text.DecimalFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-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() {
-            return new DecimalFormat();
-        }
-    };
-
-    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/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
deleted file mode 100644
index aed2ee6..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ /dev/null
@@ -1,831 +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.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.jexl2.JexlContext;
-import org.apache.commons.jexl2.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.DerAttr;
-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.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-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.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 UserDAO userDAO;
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @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.getDerAttrs(), any.getPlainAttrs(), 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 connObjectLink + 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:
-                for (Any<?, ?> any : anys) {
-                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-                    DerAttr<?> attr = any.getDerAttr(mappingItem.getIntAttrName());
-                    if (attr != null) {
-                        PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                        attrValue.setStringValue(attr.getValue(any.getPlainAttrs()));
-                        values.add(attrValue);
-                    }
-
-                    LOG.debug("Retrieved attribute {}"
-                            + "\n* IntAttrName {}"
-                            + "\n* IntMappingType {}"
-                            + "\n* Attribute values {}",
-                            attr, 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())
-                        ? null
-                        : provision.getMapping();
-                Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
-                        ? null
-                        : provision.getMapping();
-
-                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/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.java
deleted file mode 100644
index d8bacdb..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/RealmUtils.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.misc;
-
-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<>();
-        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/0211410b/core/misc/src/main/java/org/apache/syncope/core/misc/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/TemplateUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/TemplateUtils.java
deleted file mode 100644
index d990cdb..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/TemplateUtils.java
+++ /dev/null
@@ -1,223 +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.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-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<Long, RelationshipTO> anyRelMap,
-            final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
-
-        for (RelationshipTO memb : templateRels) {
-            if (!anyRelMap.containsKey(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/0211410b/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
index 3afe6e5..2870eae 100644
--- 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
@@ -35,7 +35,7 @@ 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.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.misc.FormatUtils;
+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.PlainAttr;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
index 7dc576a..f281fd3 100644
--- 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
@@ -36,8 +36,8 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.MappingUtils;
-import org.apache.syncope.core.misc.RealmUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
index 100de17..198b1e8 100644
--- 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
@@ -29,7 +29,7 @@ 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.RealmUtils;
+import org.apache.syncope.core.misc.utils.RealmUtils;
 import org.springframework.security.core.GrantedAuthority;
 
 public class SyncopeGrantedAuthority implements GrantedAuthority {


[07/10] syncope git commit: [SYNCOPE-141] Preliminary changes

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 77efd28..192b26d 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,8 +43,8 @@ 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.ConnObjectUtils;
-import org.apache.syncope.core.misc.MappingUtils;
+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.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
index e0d3d59..f938faf 100644
--- 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
@@ -37,7 +37,7 @@ 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.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
index 570cb76..d4bef63 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
@@ -32,7 +32,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
 import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.ConnObjectUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
index 1ed0d2c..34fde4d 100644
--- 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
@@ -18,13 +18,13 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import static org.apache.syncope.core.misc.MappingUtils.getMappingItemTransformers;
+import static org.apache.syncope.core.misc.utils.MappingUtils.getMappingItemTransformers;
 
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.core.misc.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
index d3a4a4d..b8e1522 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
@@ -27,7 +27,7 @@ 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.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
index 4fa504e..b0c4161 100644
--- 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
@@ -25,7 +25,7 @@ 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.policy.SyncPolicySpec;
-import org.apache.syncope.core.misc.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/core/provisioning-java/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioning.properties b/core/provisioning-java/src/main/resources/provisioning.properties
index 59e5916..55f9ead 100644
--- a/core/provisioning-java/src/main/resources/provisioning.properties
+++ b/core/provisioning-java/src/main/resources/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/core/provisioning-java/src/main/resources/provisioningContext.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index 4d635d2..7fcafc7 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -28,8 +28,13 @@ under the License.
                            http://www.springframework.org/schema/task
                            http://www.springframework.org/schema/task/spring-task.xsd">
   
-  <task:annotation-driven executor="connectorExecutor"/>
-  <task:executor id="connectorExecutor" pool-size="10"/>
+  <context:component-scan base-package="org.apache.syncope.core.provisioning.java"/>
+
+  <!-- Used by AsyncConnectorFacade -->
+  <task:annotation-driven executor="AsyncConnectorFacadeExecutor"/>
+  <task:executor id="AsyncConnectorFacadeExecutor" pool-size="${asyncConnectorFacadeExecutor.poolSize}"/>
+  
+  <bean class="${propagationTaskExecutor}"/>
   
   <bean class="${userProvisioningManager}"/>
   <bean class="${groupProvisioningManager}"/>
@@ -102,9 +107,6 @@ under the License.
   <bean class="org.apache.syncope.core.provisioning.java.propagation.PropagationManagerImpl"/>
   <bean class="org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter" scope="prototype"/>
 
-  <context:component-scan base-package="org.apache.syncope.core.misc"/>  
-  <context:component-scan base-package="org.apache.syncope.core.provisioning.java"/>
-
   <bean id="virAttrCache" class="${virAttrCache}" scope="singleton">
     <constructor-arg value="60"/>
     <constructor-arg value="5000"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 e26f238..1193e16 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,6 +27,7 @@ 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/0211410b/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 8bf191e..91486ab 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,7 @@ 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.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 fe19915..f767c19 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.FormatUtils;
+import org.apache.syncope.core.misc.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/0211410b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
index 763f666..ab3b256 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
@@ -15,6 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 camel.directory=${conf.directory}
+
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelAnyObjectProvisioningManager

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 4a3df61..3d8af35 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -770,6 +770,7 @@ under the License.
                   <resource>
                     <directory>${basedir}/../../core/misc/target/classes</directory>
                     <excludes>
+                      <exclude>utilsContext.xml</exclude>
                       <exclude>securityContext.xml</exclude>
                     </excludes>
                   </resource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/all/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/provisioning.properties b/fit/core-reference/src/main/resources/all/provisioning.properties
index 336ed21..9c979a2 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -15,6 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 camel.directory=${conf.directory}
+
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelAnyObjectProvisioningManager

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/mariadb/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/mariadb/provisioning.properties b/fit/core-reference/src/main/resources/mariadb/provisioning.properties
index 4a0c415..ca365dc 100644
--- a/fit/core-reference/src/main/resources/mariadb/provisioning.properties
+++ b/fit/core-reference/src/main/resources/mariadb/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 quartz.sql=tables_mariadb.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/mysql/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/mysql/provisioning.properties b/fit/core-reference/src/main/resources/mysql/provisioning.properties
index ac8306a..428be67 100644
--- a/fit/core-reference/src/main/resources/mysql/provisioning.properties
+++ b/fit/core-reference/src/main/resources/mysql/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 quartz.sql=tables_mysql.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/oracle/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/oracle/provisioning.properties b/fit/core-reference/src/main/resources/oracle/provisioning.properties
index 22071c0..a507de0 100644
--- a/fit/core-reference/src/main/resources/oracle/provisioning.properties
+++ b/fit/core-reference/src/main/resources/oracle/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
 quartz.sql=tables_oracle.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/postgres/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/postgres/provisioning.properties b/fit/core-reference/src/main/resources/postgres/provisioning.properties
index 66340bb..1be02bf 100644
--- a/fit/core-reference/src/main/resources/postgres/provisioning.properties
+++ b/fit/core-reference/src/main/resources/postgres/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
 quartz.sql=tables_postgres.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/provisioning.properties b/fit/core-reference/src/main/resources/provisioning.properties
index a67787f..a14ae19 100644
--- a/fit/core-reference/src/main/resources/provisioning.properties
+++ b/fit/core-reference/src/main/resources/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 quartz.sql=tables_h2.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/fit/core-reference/src/main/resources/sqlserver/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/sqlserver/provisioning.properties b/fit/core-reference/src/main/resources/sqlserver/provisioning.properties
index 5e0088e..4cb4b80 100644
--- a/fit/core-reference/src/main/resources/sqlserver/provisioning.properties
+++ b/fit/core-reference/src/main/resources/sqlserver/provisioning.properties
@@ -14,6 +14,9 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+asyncConnectorFacadeExecutor.poolSize=10
+propagationTaskExecutor=org.apache.syncope.core.provisioning.java.propagation.PriorityPropagationTaskExecutor
+
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
@@ -21,4 +24,4 @@ virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.MSSQLDelegate
 quartz.sql=tables_sqlServer.sql
-quartz.scheduler.idleWaitTime=5000
\ No newline at end of file
+quartz.scheduler.idleWaitTime=5000


[02/10] syncope git commit: Merge branch '1_2_X' of https://git-wip-us.apache.org/repos/asf/syncope into 1_2_X

Posted by il...@apache.org.
Merge branch '1_2_X' of https://git-wip-us.apache.org/repos/asf/syncope into 1_2_X


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

Branch: refs/heads/master
Commit: 56f159808c863507792752e9fd637d345d481dc1
Parents: 503097d fb57753
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Oct 19 16:36:33 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Oct 19 16:36:33 2015 +0200

----------------------------------------------------------------------
 .../core/persistence/dao/impl/SubjectSearchDAOImpl.java  | 11 ++++++++---
 .../apache/syncope/core/services/RoleServiceImpl.java    | 11 ++++++++---
 .../org/apache/syncope/core/rest/SearchTestITCase.java   |  9 +++++++++
 3 files changed, 25 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[10/10] syncope git commit: [SYNCOPE-717] Merge from 1_2_X

Posted by il...@apache.org.
[SYNCOPE-717] Merge from 1_2_X


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

Branch: refs/heads/master
Commit: e486aaf3a1ac1b5a3281a2c93598cc38cca4073e
Parents: 0211410 5954e2e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Oct 29 10:37:23 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Oct 29 10:39:43 2015 +0100

----------------------------------------------------------------------
 .../syncope/core/misc/utils/FormatUtils.java    |  6 +-
 .../syncope/fit/core/reference/GroupITCase.java | 59 ++++++++++++++++++++
 2 files changed, 64 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e486aaf3/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
----------------------------------------------------------------------
diff --cc core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
index ec5250a,0000000..131f310
mode 100644,000000..100644
--- 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
@@@ -1,117 -1,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.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() {
-             return new DecimalFormat();
++            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/e486aaf3/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index db12a2b,0000000..17ba8c8
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@@ -1,806 -1,0 +1,865 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *   http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing,
 + * software distributed under the License is distributed on an
 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 + * KIND, either express or implied.  See the License for the
 + * specific language governing permissions and limitations
 + * under the License.
 + */
 +package org.apache.syncope.fit.core.reference;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertNull;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.security.AccessControlException;
 +import java.util.List;
 +import javax.naming.NamingEnumeration;
 +import javax.naming.NamingException;
 +import javax.naming.directory.DirContext;
 +import javax.naming.directory.SearchControls;
 +import javax.naming.directory.SearchResult;
 +import javax.ws.rs.core.Response;
 +import org.apache.commons.collections4.CollectionUtils;
 +import org.apache.commons.collections4.Predicate;
 +import org.apache.commons.io.IOUtils;
 +import org.apache.commons.lang3.StringUtils;
 +import org.apache.syncope.client.lib.SyncopeClient;
 +import org.apache.syncope.common.lib.SyncopeClientException;
 +import org.apache.syncope.common.lib.SyncopeConstants;
 +import org.apache.syncope.common.lib.patch.AssociationPatch;
 +import org.apache.syncope.common.lib.patch.AttrPatch;
 +import org.apache.syncope.common.lib.patch.DeassociationPatch;
 +import org.apache.syncope.common.lib.patch.GroupPatch;
 +import org.apache.syncope.common.lib.patch.LongReplacePatchItem;
 +import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
 +import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 +import org.apache.syncope.common.lib.to.AnyTypeTO;
 +import org.apache.syncope.common.lib.to.AttrTO;
 +import org.apache.syncope.common.lib.to.BulkActionResult;
 +import org.apache.syncope.common.lib.to.ConnInstanceTO;
 +import org.apache.syncope.common.lib.to.ConnObjectTO;
 +import org.apache.syncope.common.lib.to.MappingItemTO;
 +import org.apache.syncope.common.lib.to.PagedResult;
 +import org.apache.syncope.common.lib.to.PlainSchemaTO;
 +import org.apache.syncope.common.lib.to.ResourceTO;
 +import org.apache.syncope.common.lib.to.GroupTO;
 +import org.apache.syncope.common.lib.to.MappingTO;
 +import org.apache.syncope.common.lib.to.ProvisionTO;
 +import org.apache.syncope.common.lib.to.UserTO;
 +import org.apache.syncope.common.lib.types.AnyTypeKind;
++import org.apache.syncope.common.lib.types.AttrSchemaType;
 +import org.apache.syncope.common.lib.types.ClientExceptionType;
 +import org.apache.syncope.common.lib.types.ConnectorCapability;
 +import org.apache.syncope.common.lib.types.IntMappingType;
 +import org.apache.syncope.common.lib.types.MappingPurpose;
 +import org.apache.syncope.common.lib.types.PatchOperation;
 +import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 +import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 +import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
 +import org.apache.syncope.common.lib.types.SchemaType;
 +import org.apache.syncope.common.rest.api.Preference;
 +import org.apache.syncope.common.rest.api.RESTHeaders;
 +import org.apache.syncope.common.rest.api.service.GroupService;
 +import org.junit.FixMethodOrder;
 +import org.junit.Test;
 +import org.junit.runners.MethodSorters;
 +
 +@FixMethodOrder(MethodSorters.JVM)
 +public class GroupITCase extends AbstractITCase {
 +
 +    public static GroupTO getBasicSampleTO(final String name) {
 +        GroupTO groupTO = new GroupTO();
 +        groupTO.setRealm("/");
 +        groupTO.setName(name + getUUIDString());
 +        return groupTO;
 +    }
 +
 +    public static GroupTO getSampleTO(final String name) {
 +        GroupTO groupTO = getBasicSampleTO(name);
 +
 +        groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
 +
 +        groupTO.getResources().add(RESOURCE_NAME_LDAP);
 +        return groupTO;
 +    }
 +
 +    @Test
 +    public void create() {
 +        GroupTO groupTO = getSampleTO("lastGroup");
 +        groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
 +        groupTO.setGroupOwner(8L);
 +
 +        groupTO = createGroup(groupTO);
 +        assertNotNull(groupTO);
 +
 +        assertNotNull(groupTO.getVirAttrMap());
 +        assertNotNull(groupTO.getVirAttrMap().get("rvirtualdata").getValues());
 +        assertFalse(groupTO.getVirAttrMap().get("rvirtualdata").getValues().isEmpty());
 +        assertEquals("rvirtualvalue", groupTO.getVirAttrMap().get("rvirtualdata").getValues().get(0));
 +
 +        assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
 +
 +        ConnObjectTO connObjectTO =
 +                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
 +        assertNotNull(connObjectTO);
 +        assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
 +
 +        // SYNCOPE-515: remove ownership
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(groupTO.getKey());
 +        groupPatch.setGroupOwner(new LongReplacePatchItem());
 +
 +        assertNull(updateGroup(groupPatch).getGroupOwner());
 +    }
 +
 +    @Test
 +    public void delete() {
 +        try {
 +            groupService.delete(0L);
 +        } catch (SyncopeClientException e) {
 +            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
 +        }
 +
 +        GroupTO groupTO = new GroupTO();
 +        groupTO.setName("toBeDeleted" + getUUIDString());
 +        groupTO.setRealm("/even");
 +
 +        groupTO.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        groupTO = createGroup(groupTO);
 +        assertNotNull(groupTO);
 +
 +        GroupTO deletedGroup = deleteGroup(groupTO.getKey());
 +        assertNotNull(deletedGroup);
 +
 +        try {
 +            groupService.read(deletedGroup.getKey());
 +        } catch (SyncopeClientException e) {
 +            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
 +        }
 +    }
 +
 +    @Test
 +    public void list() {
 +        PagedResult<GroupTO> groupTOs =
 +                groupService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
 +        assertNotNull(groupTOs);
 +        assertTrue(groupTOs.getResult().size() >= 8);
 +        for (GroupTO groupTO : groupTOs.getResult()) {
 +            assertNotNull(groupTO);
 +        }
 +    }
 +
 +    @Test
 +    public void read() {
 +        GroupTO groupTO = groupService.read(1L);
 +
 +        assertNotNull(groupTO);
 +        assertNotNull(groupTO.getPlainAttrs());
 +        assertFalse(groupTO.getPlainAttrs().isEmpty());
 +    }
 +
 +    @Test
 +    public void selfRead() {
 +        UserTO userTO = userService.read(1L);
 +        assertNotNull(userTO);
 +
 +        assertTrue(userTO.getMembershipMap().containsKey(1L));
 +        assertFalse(userTO.getMembershipMap().containsKey(3L));
 +
 +        GroupService groupService2 = clientFactory.create("rossini", ADMIN_PWD).getService(GroupService.class);
 +
 +        try {
 +            groupService2.read(3L);
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(ClientExceptionType.DelegatedAdministration, e.getType());
 +        }
 +
 +        List<GroupTO> groups = groupService2.own();
 +        assertNotNull(groups);
 +        assertTrue(CollectionUtils.exists(groups, new Predicate<GroupTO>() {
 +
 +            @Override
 +            public boolean evaluate(final GroupTO group) {
 +                return 1L == group.getKey();
 +            }
 +        }));
 +    }
 +
 +    @Test
 +    public void update() {
 +        GroupTO groupTO = getSampleTO("latestGroup" + getUUIDString());
 +        groupTO = createGroup(groupTO);
 +
 +        assertEquals(1, groupTO.getPlainAttrs().size());
 +
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(groupTO.getKey());
 +        String modName = "finalGroup" + getUUIDString();
 +        groupPatch.setName(new StringReplacePatchItem.Builder().value(modName).build());
 +        groupPatch.getPlainAttrs().add(attrAddReplacePatch("show", "FALSE"));
 +
 +        groupTO = updateGroup(groupPatch);
 +
 +        assertEquals(modName, groupTO.getName());
 +        assertEquals(2, groupTO.getPlainAttrs().size());
 +    }
 +
 +    @Test
 +    public void updateRemovingDerAttribute() {
 +        GroupTO groupTO = getBasicSampleTO("withderived" + getUUIDString());
 +        groupTO.getDerAttrs().add(attrTO("rderivedschema", null));
 +
 +        groupTO = createGroup(groupTO);
 +
 +        assertNotNull(groupTO);
 +        assertEquals(1, groupTO.getDerAttrs().size());
 +
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(groupTO.getKey());
 +        groupPatch.getDerAttrs().add(new AttrPatch.Builder().operation(PatchOperation.DELETE).
 +                attrTO(new AttrTO.Builder().schema("rderivedschema").build()).
 +                build());
 +
 +        groupTO = updateGroup(groupPatch);
 +        assertNotNull(groupTO);
 +        assertTrue(groupTO.getDerAttrs().isEmpty());
 +    }
 +
 +    @Test
 +    public void updateAsGroupOwner() {
 +        // 1. read group as admin
 +        GroupTO groupTO = groupService.read(6L);
 +
 +        // issue SYNCOPE-15
 +        assertNotNull(groupTO.getCreationDate());
 +        assertNotNull(groupTO.getLastChangeDate());
 +        assertEquals("admin", groupTO.getCreator());
 +        assertEquals("admin", groupTO.getLastModifier());
 +
 +        // 2. prepare update
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(groupTO.getKey());
 +        groupPatch.setName(new StringReplacePatchItem.Builder().value("Director").build());
 +
 +        // 3. try to update as verdi, not owner of group 6 - fail
 +        GroupService groupService2 = clientFactory.create("verdi", ADMIN_PWD).getService(GroupService.class);
 +
 +        try {
 +            groupService2.update(groupPatch);
 +            fail();
 +        } catch (SyncopeClientException e) {
 +            assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
 +        } catch (AccessControlException e) {
 +            assertNotNull(e);
 +        }
 +
 +        // 4. update as puccini, owner of group 6 - success
 +        GroupService groupService3 = clientFactory.create("puccini", ADMIN_PWD).getService(GroupService.class);
 +
 +        groupTO = groupService3.update(groupPatch).readEntity(GroupTO.class);
 +        assertEquals("Director", groupTO.getName());
 +
 +        // issue SYNCOPE-15
 +        assertNotNull(groupTO.getCreationDate());
 +        assertNotNull(groupTO.getLastChangeDate());
 +        assertEquals("admin", groupTO.getCreator());
 +        assertEquals("puccini", groupTO.getLastModifier());
 +        assertTrue(groupTO.getCreationDate().before(groupTO.getLastChangeDate()));
 +    }
 +
 +    @Test
 +    public void issue178() {
 +        GroupTO groupTO = new GroupTO();
 +        String groupName = "torename" + getUUIDString();
 +        groupTO.setName(groupName);
 +        groupTO.setRealm("/");
 +
 +        GroupTO actual = createGroup(groupTO);
 +
 +        assertNotNull(actual);
 +        assertEquals(groupName, actual.getName());
 +
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(actual.getKey());
 +        String renamedGroup = "renamed" + getUUIDString();
 +        groupPatch.setName(new StringReplacePatchItem.Builder().value(renamedGroup).build());
 +
 +        actual = updateGroup(groupPatch);
 +        assertNotNull(actual);
 +        assertEquals(renamedGroup, actual.getName());
 +    }
 +
 +    @Test
 +    public void unlink() {
 +        GroupTO actual = createGroup(getSampleTO("unlink"));
 +        assertNotNull(actual);
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +
 +        DeassociationPatch deassociationPatch = new DeassociationPatch();
 +        deassociationPatch.setKey(actual.getKey());
 +        deassociationPatch.setAction(ResourceDeassociationAction.UNLINK);
 +        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertTrue(actual.getResources().isEmpty());
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +    }
 +
 +    @Test
 +    public void link() {
 +        GroupTO groupTO = getSampleTO("link");
 +        groupTO.getResources().clear();
 +
 +        GroupTO actual = createGroup(groupTO);
 +        assertNotNull(actual);
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +
 +        AssociationPatch associationPatch = new AssociationPatch();
 +        associationPatch.setKey(actual.getKey());
 +        associationPatch.setAction(ResourceAssociationAction.LINK);
 +        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertFalse(actual.getResources().isEmpty());
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +    }
 +
 +    @Test
 +    public void unassign() {
 +        GroupTO actual = createGroup(getSampleTO("unassign"));
 +        assertNotNull(actual);
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +
 +        DeassociationPatch deassociationPatch = new DeassociationPatch();
 +        deassociationPatch.setKey(actual.getKey());
 +        deassociationPatch.setAction(ResourceDeassociationAction.UNASSIGN);
 +        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertTrue(actual.getResources().isEmpty());
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +    }
 +
 +    @Test
 +    public void assign() {
 +        GroupTO groupTO = getSampleTO("assign");
 +        groupTO.getResources().clear();
 +
 +        GroupTO actual = createGroup(groupTO);
 +        assertNotNull(actual);
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +
 +        AssociationPatch associationPatch = new AssociationPatch();
 +        associationPatch.setKey(actual.getKey());
 +        associationPatch.setAction(ResourceAssociationAction.ASSIGN);
 +        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertFalse(actual.getResources().isEmpty());
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +    }
 +
 +    @Test
 +    public void deprovision() {
 +        GroupTO actual = createGroup(getSampleTO("deprovision"));
 +        assertNotNull(actual);
 +        assertNotNull(actual.getKey());
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +
 +        DeassociationPatch deassociationPatch = new DeassociationPatch();
 +        deassociationPatch.setKey(actual.getKey());
 +        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
 +        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertFalse(actual.getResources().isEmpty());
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +    }
 +
 +    @Test
 +    public void provision() {
 +        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
 +        groupTO.getResources().clear();
 +
 +        GroupTO actual = createGroup(groupTO);
 +        assertNotNull(actual);
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +
 +        AssociationPatch associationPatch = new AssociationPatch();
 +        associationPatch.setKey(actual.getKey());
 +        associationPatch.setAction(ResourceAssociationAction.PROVISION);
 +        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertTrue(actual.getResources().isEmpty());
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +    }
 +
 +    @Test
 +    public void deprovisionUnlinked() {
 +        GroupTO groupTO = getSampleTO("assign" + getUUIDString());
 +        groupTO.getResources().clear();
 +
 +        GroupTO actual = createGroup(groupTO);
 +        assertNotNull(actual);
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +
 +        AssociationPatch associationPatch = new AssociationPatch();
 +        associationPatch.setKey(actual.getKey());
 +        associationPatch.setAction(ResourceAssociationAction.PROVISION);
 +        associationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.associate(associationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertTrue(actual.getResources().isEmpty());
 +
 +        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 +
 +        DeassociationPatch deassociationPatch = new DeassociationPatch();
 +        deassociationPatch.setKey(actual.getKey());
 +        deassociationPatch.setAction(ResourceDeassociationAction.DEPROVISION);
 +        deassociationPatch.getResources().add(RESOURCE_NAME_LDAP);
 +
 +        assertNotNull(groupService.deassociate(deassociationPatch).readEntity(BulkActionResult.class));
 +
 +        actual = groupService.read(actual.getKey());
 +        assertNotNull(actual);
 +        assertTrue(actual.getResources().isEmpty());
 +
 +        try {
 +            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
 +            fail();
 +        } catch (Exception e) {
 +            assertNotNull(e);
 +        }
 +    }
 +
 +    @Test
 +    public void createWithMandatorySchema() {
 +        // 1. create a mandatory schema
 +        PlainSchemaTO badge = new PlainSchemaTO();
 +        badge.setKey("badge" + getUUIDString());
 +        badge.setMandatoryCondition("true");
 +        schemaService.create(SchemaType.PLAIN, badge);
 +
 +        // 2. create a group *without* an attribute for that schema: it works
 +        GroupTO groupTO = getSampleTO("lastGroup");
 +        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
 +        groupTO = createGroup(groupTO);
 +        assertNotNull(groupTO);
 +        assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
 +
 +        // 3. add the new mandatory schema to the default group type
 +        AnyTypeTO type = anyTypeService.read(AnyTypeKind.GROUP.name());
 +        String typeClassName = type.getClasses().get(0);
 +        AnyTypeClassTO typeClass = anyTypeClassService.read(typeClassName);
 +        typeClass.getPlainSchemas().add(badge.getKey());
 +        anyTypeClassService.update(typeClass);
 +        typeClass = anyTypeClassService.read(typeClassName);
 +        assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
 +
 +        try {
 +            // 4. update group: failure since no values are provided and it is mandatory
 +            GroupPatch groupPatch = new GroupPatch();
 +            groupPatch.setKey(groupTO.getKey());
 +
 +            try {
 +                updateGroup(groupPatch);
 +                fail();
 +            } catch (SyncopeClientException e) {
 +                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
 +            }
 +
 +            // 5. also add an actual attribute for badge - it will work        
 +            groupPatch.getPlainAttrs().add(attrAddReplacePatch(badge.getKey(), "xxxxxxxxxx"));
 +
 +            groupTO = updateGroup(groupPatch);
 +            assertNotNull(groupTO);
 +            assertTrue(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
 +        } finally {
 +            // restore the original group class
 +            typeClass.getPlainSchemas().remove(badge.getKey());
 +            anyTypeClassService.update(typeClass);
 +            typeClass = anyTypeClassService.read(typeClassName);
 +            assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
 +        }
 +    }
 +
 +    @Test
 +    public void anonymous() {
 +        GroupService unauthenticated = clientFactory.create().getService(GroupService.class);
 +        try {
 +            unauthenticated.
 +                    list(SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
 +            fail();
 +        } catch (AccessControlException e) {
 +            assertNotNull(e);
 +        }
 +
 +        GroupService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(GroupService.class);
 +        assertFalse(anonymous.list(SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
 +                build()).
 +                getResult().isEmpty());
 +    }
 +
 +    @Test
 +    public void noContent() throws IOException {
 +        SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
 +        GroupService noContentService = noContentclient.prefer(GroupService.class, Preference.RETURN_NO_CONTENT);
 +
 +        GroupTO group = getSampleTO("noContent");
 +
 +        Response response = noContentService.create(group);
 +        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
 +        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
 +        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
 +
 +        group = getObject(response.getLocation(), GroupService.class, GroupTO.class);
 +        assertNotNull(group);
 +
 +        GroupPatch groupPatch = new GroupPatch();
 +        groupPatch.setKey(group.getKey());
 +        groupPatch.getPlainAttrs().add(attrAddReplacePatch("badge", "xxxxxxxxxx"));
 +
 +        response = noContentService.update(groupPatch);
 +        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
 +        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
 +        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
 +
 +        response = noContentService.delete(group.getKey());
 +        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
 +        assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
 +        assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
 +    }
 +
 +    @Test
 +    public void dynMembership() {
 +        assertTrue(userService.read(4L).getDynGroups().isEmpty());
 +
 +        GroupTO group = getBasicSampleTO("dynMembership");
 +        group.setUDynMembershipCond("cool==true");
 +        group = createGroup(group);
 +        assertNotNull(group);
 +
 +        assertTrue(userService.read(4L).getDynGroups().contains(group.getKey()));
 +
 +        GroupPatch mod = new GroupPatch();
 +        mod.setKey(group.getKey());
 +        mod.setUDynMembershipCond(new StringReplacePatchItem.Builder().value("cool==false").build());
 +        groupService.update(mod);
 +
 +        assertTrue(userService.read(4L).getDynGroups().isEmpty());
 +    }
 +
 +    @Test
 +    public void capabilitiesOverride() {
 +        // resource with no capability override
 +        ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
 +        assertNotNull(ldap);
 +        assertFalse(ldap.isOverrideCapabilities());
 +        assertTrue(ldap.getCapabilitiesOverride().isEmpty());
 +
 +        // connector with all required for create and update
 +        ConnInstanceTO conn = connectorService.read(ldap.getConnector(), null);
 +        assertNotNull(conn);
 +        assertTrue(conn.getCapabilities().contains(ConnectorCapability.CREATE));
 +        assertTrue(conn.getCapabilities().contains(ConnectorCapability.UPDATE));
 +
 +        try {
 +            // 1. create succeeds
 +            GroupTO group = getSampleTO("syncope714");
 +            group.getPlainAttrs().add(attrTO("title", "first"));
 +            group.getResources().add(RESOURCE_NAME_LDAP);
 +
 +            group = createGroup(group);
 +            assertNotNull(group);
 +            assertEquals(1, group.getPropagationStatusTOs().size());
 +            assertEquals(RESOURCE_NAME_LDAP, group.getPropagationStatusTOs().get(0).getResource());
 +            assertEquals(PropagationTaskExecStatus.SUCCESS, group.getPropagationStatusTOs().get(0).getStatus());
 +
 +            // 2. update succeeds
 +            GroupPatch patch = new GroupPatch();
 +            patch.setKey(group.getKey());
 +            patch.getPlainAttrs().add(new AttrPatch.Builder().
 +                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "second")).build());
 +
 +            group = groupService.update(patch).readEntity(GroupTO.class);
 +            assertNotNull(group);
 +            assertEquals(1, group.getPropagationStatusTOs().size());
 +            assertEquals(RESOURCE_NAME_LDAP, group.getPropagationStatusTOs().get(0).getResource());
 +            assertEquals(PropagationTaskExecStatus.SUCCESS, group.getPropagationStatusTOs().get(0).getStatus());
 +
 +            // 3. set capability override with only search allowed, but not enable
 +            ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
 +            resourceService.update(ldap);
 +            ldap = resourceService.read(RESOURCE_NAME_LDAP);
 +            assertNotNull(ldap);
 +            assertFalse(ldap.isOverrideCapabilities());
 +            assertEquals(1, ldap.getCapabilitiesOverride().size());
 +            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
 +
 +            // 4. update succeeds again
 +            patch = new GroupPatch();
 +            patch.setKey(group.getKey());
 +            patch.getPlainAttrs().add(new AttrPatch.Builder().
 +                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "third")).build());
 +
 +            group = groupService.update(patch).readEntity(GroupTO.class);
 +            assertNotNull(group);
 +            assertEquals(1, group.getPropagationStatusTOs().size());
 +            assertEquals(RESOURCE_NAME_LDAP, group.getPropagationStatusTOs().get(0).getResource());
 +            assertEquals(PropagationTaskExecStatus.SUCCESS, group.getPropagationStatusTOs().get(0).getStatus());
 +
 +            // 5. enable capability override
 +            ldap.setOverrideCapabilities(true);
 +            resourceService.update(ldap);
 +            ldap = resourceService.read(RESOURCE_NAME_LDAP);
 +            assertNotNull(ldap);
 +            assertTrue(ldap.isOverrideCapabilities());
 +            assertEquals(1, ldap.getCapabilitiesOverride().size());
 +            assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
 +
 +            // 6. update now fails
 +            patch = new GroupPatch();
 +            patch.setKey(group.getKey());
 +            patch.getPlainAttrs().add(new AttrPatch.Builder().
 +                    operation(PatchOperation.ADD_REPLACE).attrTO(attrTO("title", "fourth")).build());
 +
 +            group = groupService.update(patch).readEntity(GroupTO.class);
 +            assertNotNull(group);
 +            assertEquals(1, group.getPropagationStatusTOs().size());
 +            assertEquals(RESOURCE_NAME_LDAP, group.getPropagationStatusTOs().get(0).getResource());
 +            assertEquals(PropagationTaskExecStatus.NOT_ATTEMPTED, group.getPropagationStatusTOs().get(0).getStatus());
 +        } finally {
 +            ldap.getCapabilitiesOverride().clear();
 +            ldap.setOverrideCapabilities(false);
 +            resourceService.update(ldap);
 +        }
 +    }
 +
 +    @Test
 +    public void issueSYNCOPE632() {
 +        GroupTO groupTO = null;
 +        try {
 +            // 1. create new LDAP resource having ConnObjectKey mapped to a derived attribute
 +            ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP);
 +            newLDAP.setKey("new-ldap");
 +            newLDAP.setPropagationPrimary(true);
 +
 +            for (ProvisionTO provision : newLDAP.getProvisions()) {
 +                provision.getVirSchemas().clear();
 +            }
 +
 +            MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
 +
 +            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
 +            connObjectKey.setIntMappingType(IntMappingType.GroupDerivedSchema);
 +            connObjectKey.setIntAttrName("displayProperty");
 +            mapping.setConnObjectKeyItem(connObjectKey);
 +            mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
 +
 +            MappingItemTO description = new MappingItemTO();
 +            description.setIntMappingType(IntMappingType.GroupKey);
 +            description.setExtAttrName("description");
 +            description.setPurpose(MappingPurpose.BOTH);
 +            mapping.add(description);
 +
 +            newLDAP = createResource(newLDAP);
 +            assertNotNull(newLDAP);
 +
 +            // 2. create a group and give the resource created above
 +            groupTO = getSampleTO("lastGroup" + getUUIDString());
 +            groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
 +            groupTO.getPlainAttrs().add(attrTO("show", "true"));
 +            groupTO.getDerAttrs().add(attrTO("displayProperty", null));
 +            groupTO.getResources().clear();
 +            groupTO.getResources().add("new-ldap");
 +
 +            groupTO = createGroup(groupTO);
 +            assertNotNull(groupTO);
 +
 +            // 3. update the group
 +            GroupPatch groupPatch = new GroupPatch();
 +            groupPatch.setKey(groupTO.getKey());
 +            groupPatch.getPlainAttrs().add(attrAddReplacePatch("icon", "anotherIcon"));
 +
 +            groupTO = updateGroup(groupPatch);
 +            assertNotNull(groupTO);
 +
 +            // 4. check that a single group exists in LDAP for the group created and updated above
 +            int entries = 0;
 +            DirContext ctx = null;
 +            try {
 +                ctx = getLdapResourceDirContext(null, null);
 +
 +                SearchControls ctls = new SearchControls();
 +                ctls.setReturningAttributes(new String[] { "*", "+" });
 +                ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
 +
 +                NamingEnumeration<SearchResult> result =
 +                        ctx.search("ou=groups,o=isp", "(description=" + groupTO.getKey() + ")", ctls);
 +                while (result.hasMore()) {
 +                    result.next();
 +                    entries++;
 +                }
 +            } catch (Exception e) {
 +                // ignore
 +            } finally {
 +                if (ctx != null) {
 +                    try {
 +                        ctx.close();
 +                    } catch (NamingException e) {
 +                        // ignore
 +                    }
 +                }
 +            }
 +
 +            assertEquals(1, entries);
 +        } finally {
 +            if (groupTO != null) {
 +                groupService.delete(groupTO.getKey());
 +            }
 +            resourceService.delete("new-ldap");
 +        }
 +    }
 +
++    @Test
++    public void issueSYNCOPE717() {
++        String doubleSchemaName = "double" + getUUIDString();
++
++        // 1. create double schema without conversion pattern
++        PlainSchemaTO schema = new PlainSchemaTO();
++        schema.setKey(doubleSchemaName);
++        schema.setType(AttrSchemaType.Double);
++
++        schema = createSchema(SchemaType.PLAIN, schema);
++        assertNotNull(schema);
++        assertNull(schema.getConversionPattern());
++
++        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
++        assertNotNull(minimalGroup);
++        minimalGroup.getPlainSchemas().add(doubleSchemaName);
++        anyTypeClassService.update(minimalGroup);
++
++        // 2. create group, provide valid input value
++        GroupTO groupTO = getBasicSampleTO("syncope717");
++        groupTO.getPlainAttrs().add(attrTO(doubleSchemaName, "11.23"));
++
++        groupTO = createGroup(groupTO);
++        assertNotNull(groupTO);
++        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
++
++        // 3. update schema, set conversion pattern
++        schema.setConversionPattern("0.000");
++        schemaService.update(SchemaType.PLAIN, schema);
++
++        // 4. re-read group, verify that pattern was applied
++        groupTO = groupService.read(groupTO.getKey());
++        assertNotNull(groupTO);
++        assertEquals("11.230", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
++
++        // 5. modify group with new double value
++        GroupPatch patch = new GroupPatch();
++        patch.setKey(groupTO.getKey());
++        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.257")).build());
++
++        groupTO = updateGroup(patch);
++        assertNotNull(groupTO);
++        assertEquals("11.257", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
++
++        // 6. update schema, unset conversion pattern
++        schema.setConversionPattern(null);
++        schemaService.update(SchemaType.PLAIN, schema);
++
++        // 7. modify group with new double value, verify that no pattern is applied
++        patch = new GroupPatch();
++        patch.setKey(groupTO.getKey());
++        patch.getPlainAttrs().add(new AttrPatch.Builder().attrTO(attrTO(doubleSchemaName, "11.23")).build());
++
++        groupTO = updateGroup(patch);
++        assertNotNull(groupTO);
++        assertEquals("11.23", groupTO.getPlainAttrMap().get(doubleSchemaName).getValues().get(0));
++    }
++
 +}


[03/10] syncope git commit: ConnId AD 1.2.4

Posted by il...@apache.org.
ConnId AD 1.2.4


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

Branch: refs/heads/master
Commit: 4dd345565388678ac3fd091aa1c49aa53cab20d6
Parents: 56f1598
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Oct 19 18:08:29 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Oct 19 18:08:29 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/4dd34556/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 4ef0802..7c0e39a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -333,7 +333,7 @@ under the License.
     <connid.db.table.version>2.2.2</connid.db.table.version>
     <connid.csvdir.version>0.8.2</connid.csvdir.version>
     <connid.ldap.version>1.4.0</connid.ldap.version>
-    <connid.ad.version>1.2.3</connid.ad.version>
+    <connid.ad.version>1.2.4</connid.ad.version>
 
     <commons-jexl.version>2.1.1</commons-jexl.version>
     <commons-lang.version>3.3.2</commons-lang.version>


[06/10] syncope git commit: [SYNCOPE-717] Fixing locale issue with conversion pattern on core, replacing SpinnerFieldPanel with new AjaxDoubleFieldPanel on console

Posted by il...@apache.org.
[SYNCOPE-717] Fixing locale issue with conversion pattern on core, replacing SpinnerFieldPanel with new AjaxDoubleFieldPanel on console


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

Branch: refs/heads/master
Commit: 5954e2e7d44878c0f87d594140f6cc42146ad5c3
Parents: 893d889
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Oct 28 14:13:40 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Oct 28 14:13:40 2015 +0100

----------------------------------------------------------------------
 .../console/pages/panels/AttributesPanel.java   |   7 +-
 .../markup/html/form/AjaxDoubleFieldPanel.java  | 196 +++++++++++++++++++
 .../wicket/markup/html/form/FieldPanel.java     |   2 +-
 .../console/SyncopeApplication.properties       |   1 +
 .../console/SyncopeApplication_it.properties    |   1 +
 .../console/SyncopeApplication_pt_BR.properties |   1 +
 .../markup/html/form/AjaxDoubleFieldPanel.html  |  23 +++
 .../apache/syncope/core/util/DataFormat.java    |   6 +-
 .../syncope/core/rest/RoleTestITCase.java       |  43 ++++
 pom.xml                                         |   1 +
 10 files changed, 275 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/java/org/apache/syncope/console/pages/panels/AttributesPanel.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/syncope/console/pages/panels/AttributesPanel.java b/console/src/main/java/org/apache/syncope/console/pages/panels/AttributesPanel.java
index da97a45..8e44f85 100644
--- a/console/src/main/java/org/apache/syncope/console/pages/panels/AttributesPanel.java
+++ b/console/src/main/java/org/apache/syncope/console/pages/panels/AttributesPanel.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.console.pages.panels;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
@@ -28,7 +27,6 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -52,6 +50,7 @@ import org.apache.syncope.console.rest.ConfigurationRestClient;
 import org.apache.syncope.console.rest.RoleRestClient;
 import org.apache.syncope.console.rest.SchemaRestClient;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.console.wicket.markup.html.form.AjaxDoubleFieldPanel;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.console.wicket.markup.html.form.BinaryFieldPanel;
@@ -318,8 +317,8 @@ public class AttributesPanel extends Panel {
                 break;
 
             case Double:
-                panel = new SpinnerFieldPanel<Double>("panel", schemaTO.getName(),
-                        Double.class, new Model<Double>(), null, null);
+                panel = new AjaxDoubleFieldPanel("panel", schemaTO.getName(), schemaTO.getConversionPattern(),
+                        new Model<Double>());
 
                 if (required) {
                     panel.addRequiredLabel();

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.java b/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.java
new file mode 100644
index 0000000..a5f8129
--- /dev/null
+++ b/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.console.wicket.markup.html.form;
+
+import java.io.Serializable;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Pattern;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.console.SyncopeSession;
+import org.apache.syncope.console.commons.Constants;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+public class AjaxDoubleFieldPanel extends FieldPanel<Double> {
+
+    private static final long serialVersionUID = 935151916638207380L;
+
+    private static final Pattern ENGLISH_DOUBLE_PATTERN = Pattern.compile("\\d+\\.\\d+");
+
+    private static final Pattern OTHER_DOUBLE_PATTERN = Pattern.compile("\\d+,\\d+");
+
+    private final String name;
+
+    private final Pattern pattern;
+
+    private final DecimalFormat englishDf;
+
+    private final DecimalFormat localeDf;
+
+    public AjaxDoubleFieldPanel(
+            final String id, final String name, final String conversionPattern, final IModel<Double> model) {
+
+        super(id, model);
+
+        this.name = name;
+
+        this.pattern = SyncopeSession.get().getLocale().equals(Locale.ENGLISH)
+                ? ENGLISH_DOUBLE_PATTERN
+                : OTHER_DOUBLE_PATTERN;
+
+        englishDf = new DecimalFormat();
+        englishDf.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+        if (StringUtils.isNotBlank(conversionPattern)) {
+            englishDf.applyPattern(conversionPattern);
+        }
+        localeDf = new DecimalFormat();
+        localeDf.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(SyncopeSession.get().getLocale()));
+        if (StringUtils.isNotBlank(conversionPattern)) {
+            localeDf.applyPattern(conversionPattern);
+        }
+
+        field = new TextField<Double>("doubleField", model) {
+
+            private static final long serialVersionUID = -378877047108711669L;
+
+            @Override
+            protected void convertInput() {
+                if (StringUtils.isNotBlank(getInput())) {
+                    if (pattern.matcher(getInput()).matches()) {
+                        Double value;
+                        try {
+                            value = localeDf.parse(getInput()).doubleValue();
+                            setConvertedInput(value);
+                        } catch (ParseException e) {
+                            error(name + ": " + getString("textField.DoubleValidator"));
+                        }
+                    } else {
+                        error(name + ": " + getString("textField.DoubleValidator"));
+                    }
+                }
+            }
+        };
+        add(field.setLabel(new Model<String>(name)).setOutputMarkupId(true));
+
+        if (!isReadOnly()) {
+            field.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+                private static final long serialVersionUID = -1107858522700306810L;
+
+                @Override
+                protected void onUpdate(final AjaxRequestTarget target) {
+                    // nothing to do
+                }
+            });
+        }
+    }
+
+    @Override
+    public FieldPanel<Double> addRequiredLabel() {
+        if (!isRequired()) {
+            setRequired(true);
+        }
+
+        this.isRequiredLabelAdded = true;
+
+        return this;
+    }
+
+    @Override
+    public FieldPanel<Double> setNewModel(final List<Serializable> list) {
+        setNewModel(new Model<Double>() {
+
+            private static final long serialVersionUID = 527651414610325237L;
+
+            @Override
+            public Double getObject() {
+                Double value = null;
+
+                if (list != null && !list.isEmpty()) {
+                    try {
+                        value = englishDf.parse(list.get(0).toString()).doubleValue();
+                    } catch (ParseException e) {
+                        error(name + ": " + getString("textField.DoubleValidator"));
+                    }
+                }
+
+                return value;
+            }
+
+            @Override
+            public void setObject(final Double object) {
+                list.clear();
+                if (object != null) {
+                    list.add(englishDf.format(object));
+                }
+            }
+        });
+
+        return this;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public FieldPanel<Double> setNewModel(final ListItem item) {
+        IModel<Double> model = new Model<Double>() {
+
+            private static final long serialVersionUID = 6799404673615637845L;
+
+            @Override
+            public Double getObject() {
+                Double value = null;
+
+                final Object obj = item.getModelObject();
+
+                if (obj != null && !obj.toString().isEmpty()) {
+                    if (obj instanceof String) {
+                        try {
+                            value = englishDf.parse(obj.toString()).doubleValue();
+                        } catch (ParseException e) {
+                            error(name + ": " + getString("textField.DoubleValidator"));
+                        }
+                    } else if (obj instanceof Double) {
+                        // Don't parse anything
+                        value = (Double) obj;
+                    }
+                }
+
+                return value;
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public void setObject(final Double object) {
+                item.setModelObject(englishDf.format(object));
+            }
+        };
+
+        field.setModel(model);
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/FieldPanel.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/FieldPanel.java b/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/FieldPanel.java
index 967f369..ae02f87 100644
--- a/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/FieldPanel.java
+++ b/console/src/main/java/org/apache/syncope/console/wicket/markup/html/form/FieldPanel.java
@@ -126,7 +126,7 @@ public abstract class FieldPanel<T> extends AbstractFieldPanel<T> implements Clo
     }
 
     public T getModelObject() {
-        return (T) field.getModelObject();
+        return field.getModelObject();
     }
 
     public FieldPanel<T> setNewModel(final IModel<T> model) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/resources/org/apache/syncope/console/SyncopeApplication.properties
----------------------------------------------------------------------
diff --git a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication.properties b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication.properties
index 223b27a..c733b09 100644
--- a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication.properties
+++ b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication.properties
@@ -52,3 +52,4 @@ jexl_ex1=surname + ',' + firstname
 jexl_ex2='new.' + surname
 jexl_syntax_url=Full JEXL reference
 create=Create
+textField.DoubleValidator=Double value not valid

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_it.properties
----------------------------------------------------------------------
diff --git a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_it.properties b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_it.properties
index 3a54be5..9f3d00c 100644
--- a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_it.properties
+++ b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_it.properties
@@ -51,3 +51,4 @@ jexl_ex1=surname + ',' + firstname
 jexl_ex2='new.' + surname
 jexl_syntax_url=Sintassi JEXL completa
 create=Crea
+textField.DoubleValidator=Valore double non valido

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_pt_BR.properties
----------------------------------------------------------------------
diff --git a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_pt_BR.properties b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_pt_BR.properties
index dd9ecd7..653983d 100644
--- a/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_pt_BR.properties
+++ b/console/src/main/resources/org/apache/syncope/console/SyncopeApplication_pt_BR.properties
@@ -51,3 +51,4 @@ jexl_ex1=sobrenome + ',' + nome
 jexl_ex2='novo.' + sobrenome
 jexl_syntax_url=Refer\u00eancia JEXL completa
 create=Criar
+textField.DoubleValidator=Double valor n\u00e3o \u00e9 v\u00e1lido

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/console/src/main/resources/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.html
----------------------------------------------------------------------
diff --git a/console/src/main/resources/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.html b/console/src/main/resources/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.html
new file mode 100644
index 0000000..050ff2d
--- /dev/null
+++ b/console/src/main/resources/org/apache/syncope/console/wicket/markup/html/form/AjaxDoubleFieldPanel.html
@@ -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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <input type="text" class="ui-widget-content ui-corner-all long_dynamicsize" wicket:id="doubleField"/>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/core/src/main/java/org/apache/syncope/core/util/DataFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/util/DataFormat.java b/core/src/main/java/org/apache/syncope/core/util/DataFormat.java
index 58b719a..4296422 100644
--- a/core/src/main/java/org/apache/syncope/core/util/DataFormat.java
+++ b/core/src/main/java/org/apache/syncope/core/util/DataFormat.java
@@ -19,9 +19,11 @@
 package org.apache.syncope.core.util;
 
 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.SyncopeConstants;
 
@@ -44,7 +46,9 @@ public final class DataFormat {
 
         @Override
         protected DecimalFormat initialValue() {
-            return new DecimalFormat();
+            DecimalFormat df = new DecimalFormat();
+            df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+            return df;
         }
     };
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
index 5f0feb0..ce553cc 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java
@@ -51,6 +51,7 @@ import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.to.SchemaTO;
 import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.common.types.AttributableType;
+import org.apache.syncope.common.types.AttributeSchemaType;
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.types.IntMappingType;
 import org.apache.syncope.common.types.MappingPurpose;
@@ -886,4 +887,46 @@ public class RoleTestITCase extends AbstractTest {
             resourceService.delete("new-ldap");
         }
     }
+
+    @Test
+    public void issueSYNCOPE717() {
+        String doubleSchemaName = "double" + getUUIDString();
+
+        // 1. create double schema without conversion pattern
+        SchemaTO schema = new SchemaTO();
+        schema.setName(doubleSchemaName);
+        schema.setType(AttributeSchemaType.Double);
+
+        schema = createSchema(AttributableType.ROLE, SchemaType.NORMAL, schema);
+        assertNotNull(schema);
+        assertNull(schema.getConversionPattern());
+
+        // 2. create role, provide valid input value
+        RoleTO roleTO = buildBasicRoleTO("syncope717");
+        roleTO.getRAttrTemplates().add(doubleSchemaName);
+        roleTO.getAttrs().add(attributeTO(doubleSchemaName, "11.23"));
+
+        roleTO = createRole(roleTO);
+        assertNotNull(roleTO);
+        assertEquals("11.23", roleTO.getAttrMap().get(doubleSchemaName).getValues().get(0));
+
+        // 3. update schema, set conversion pattern
+        schema.setConversionPattern("0.000");
+        schemaService.update(AttributableType.ROLE, SchemaType.NORMAL, schema.getName(), schema);
+
+        // 4. re-read role, verify that pattern was applied
+        roleTO = roleService.read(roleTO.getId());
+        assertNotNull(roleTO);
+        assertEquals("11.230", roleTO.getAttrMap().get(doubleSchemaName).getValues().get(0));
+
+        // 5. modify role with new double value
+        RoleMod roleMod = new RoleMod();
+        roleMod.setId(roleTO.getId());
+        roleMod.getAttrsToRemove().add(doubleSchemaName);
+        roleMod.getAttrsToUpdate().add(attributeMod(doubleSchemaName, "11.257"));
+
+        roleTO = updateRole(roleMod);
+        assertNotNull(roleTO);
+        assertEquals("11.257", roleTO.getAttrMap().get(doubleSchemaName).getValues().get(0));
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/5954e2e7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 3b74d7d..65dd922 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1026,6 +1026,7 @@ under the License.
           <configuration>
             <source>${targetJdk}</source>
             <target>${targetJdk}</target>
+            <useIncrementalCompilation>false</useIncrementalCompilation>
             <showWarnings>true</showWarnings>
             <showDeprecation>true</showDeprecation>
             <!--<compilerArgument>-Xlint:unchecked</compilerArgument>-->


[05/10] syncope git commit: [SYNCOPE-716] Fixed

Posted by il...@apache.org.
[SYNCOPE-716] Fixed


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

Branch: refs/heads/master
Commit: 893d88901513100e3daf5d4d5b4b47a3f72f9aea
Parents: d2f57ab
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Oct 27 10:09:15 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Oct 27 10:09:15 2015 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/syncope/console/pages/SchemaModalPage.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/893d8890/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
----------------------------------------------------------------------
diff --git a/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java b/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
index 1e634f0..a0415ac 100644
--- a/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
+++ b/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
@@ -169,6 +169,7 @@ public class SchemaModalPage extends AbstractSchemaModalPage<SchemaTO> {
                         enumParams, enumerationValuesPanel, enumerationValues, enumerationKeys,
                         encryptedParams, secretKey, cipherAlgorithm,
                         binaryParams, mimeType);
+                target.add(conversionParams);
                 target.add(typeParams);
             }
         });


[08/10] syncope git commit: [SYNCOPE-141] Preliminary changes

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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
new file mode 100644
index 0000000..97bf8d8
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.common.lib.types.AnyTypeKind;
+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 (AnyTypeKind.USER == anyUtils.getAnyTypeKind()) {
+            // 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);
+        } else if (AnyTypeKind.GROUP == anyUtils.getAnyTypeKind()) {
+            return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
+        } else if (AnyTypeKind.ANY_OBJECT == anyUtils.getAnyTypeKind()) {
+            return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
+        }
+
+        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();
+
+        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/0211410b/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
new file mode 100644
index 0000000..76ba64f
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/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.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/0211410b/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
new file mode 100644
index 0000000..ec5250a
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+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() {
+            return new DecimalFormat();
+        }
+    };
+
+    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/0211410b/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
new file mode 100644
index 0000000..bc7c6b8
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
@@ -0,0 +1,831 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.jexl2.JexlContext;
+import org.apache.commons.jexl2.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.DerAttr;
+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.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+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.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 UserDAO userDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @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.getDerAttrs(), any.getPlainAttrs(), 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 connObjectLink + 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:
+                for (Any<?, ?> any : anys) {
+                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                    DerAttr<?> attr = any.getDerAttr(mappingItem.getIntAttrName());
+                    if (attr != null) {
+                        PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                        attrValue.setStringValue(attr.getValue(any.getPlainAttrs()));
+                        values.add(attrValue);
+                    }
+
+                    LOG.debug("Retrieved attribute {}"
+                            + "\n* IntAttrName {}"
+                            + "\n* IntMappingType {}"
+                            + "\n* Attribute values {}",
+                            attr, 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())
+                        ? null
+                        : provision.getMapping();
+                Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
+                        ? null
+                        : provision.getMapping();
+
+                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/0211410b/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
new file mode 100644
index 0000000..cddda67
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.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.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<>();
+        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/0211410b/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
new file mode 100644
index 0000000..4b990f2
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.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<Long, RelationshipTO> anyRelMap,
+            final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
+
+        for (RelationshipTO memb : templateRels) {
+            if (!anyRelMap.containsKey(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/0211410b/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
new file mode 100644
index 0000000..7b2c9b3
--- /dev/null
+++ b/core/misc/src/main/resources/utilsContext.xml
@@ -0,0 +1,32 @@
+<?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/0211410b/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 125b447..9cf2b32 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.FormatUtils;
+import org.apache.syncope.core.misc.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/0211410b/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 9512849..3c8b0ad 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,7 +50,7 @@ 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.FormatUtils;
+import org.apache.syncope.core.misc.utils.FormatUtils;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 2acd683..f02b4ba 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,7 +39,7 @@ import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.misc.utils.RealmUtils;
 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/0211410b/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 4c29c90..86e6275 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,7 +38,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.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.RealmUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 7032df6..754da9f 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,7 +32,7 @@ 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.FormatUtils;
+import org.apache.syncope.core.misc.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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 8640c50..126c1e1 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
@@ -31,7 +31,7 @@ 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.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.MappingUtils;
+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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 94c68ee..182d3cf 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
@@ -28,7 +28,7 @@ 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.MappingUtils;
+import org.apache.syncope.core.misc.utils.MappingUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 93a0b31..4af649f 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
@@ -63,8 +63,8 @@ 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.ConnObjectUtils;
-import org.apache.syncope.core.misc.MappingUtils;
+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.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 af7f0a0..3bb1ed6 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
@@ -24,7 +24,7 @@ import org.apache.commons.collections4.Predicate;
 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.TemplateUtils;
+import org.apache.syncope.core.misc.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/0211410b/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 32a095b..e0f8cd8 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
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 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.TemplateUtils;
+import org.apache.syncope.core.misc.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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 3042239..e3b06b8 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
@@ -21,7 +21,7 @@ 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.ExceptionUtils2;
+import org.apache.syncope.core.misc.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;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 7c6d34c..e3682de 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
@@ -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.commons.lang3.ClassUtils;
-import org.apache.syncope.core.misc.FormatUtils;
+import org.apache.syncope.core.misc.utils.FormatUtils;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 e87cd00..d513069 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
@@ -46,9 +46,9 @@ 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.ConnObjectUtils;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.misc.MappingUtils;
+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.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0211410b/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 22feb44..d635e15 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
@@ -24,7 +24,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.ConnObjectUtils;
+import org.apache.syncope.core.misc.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/0211410b/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 a3c4951..90d56ba 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
@@ -31,20 +31,19 @@ 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;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.springframework.stereotype.Component;
 
-@Component
+/**
+ * Sort the given collection by looking at related ExternalResource's priority, then execute.
+ */
 public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExecutor {
 
-    /**
-     * Sort the given collection by looking at related ExternalResource's priority, then execute.
-     * {@inheritDoc}
-     */
     @Override
     public void execute(final Collection<PropagationTask> tasks, final PropagationReporter reporter) {
-        final List<PropagationTask> prioritizedTasks = new ArrayList<>(tasks);
+        List<PropagationTask> prioritizedTasks = new ArrayList<>(tasks);
         Collections.sort(prioritizedTasks, new PriorityComparator());
 
+        LOG.debug("Propagation tasks sorted by priority, before execution: {}", prioritizedTasks);
+
         Result result = Result.SUCCESS;
 
         try {