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

[42/57] syncope git commit: [SYNCOPE-119] New security model implemented

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
index 2c94b8b..643da62 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
@@ -54,8 +54,8 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
@@ -86,9 +86,11 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.java.VirAttrHandler;
-import org.apache.syncope.core.misc.MappingUtil;
-import org.apache.syncope.core.misc.jexl.JexlUtil;
+import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.misc.jexl.JexlUtils;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -101,6 +103,9 @@ abstract class AbstractAttributableDataBinder {
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractAttributableDataBinder.class);
 
     @Autowired
+    protected RealmDAO realmDAO;
+
+    @Autowired
     protected GroupDAO groupDAO;
 
     @Autowired
@@ -140,11 +145,22 @@ abstract class AbstractAttributableDataBinder {
     protected EntityFactory entityFactory;
 
     @Autowired
-    protected AttributableUtilFactory attrUtilFactory;
+    protected AttributableUtilsFactory attrUtilsFactory;
 
     @Autowired
     protected VirAttrHandler virtAttrHander;
 
+    protected void setRealm(final Subject<?, ?, ?> subject, final AbstractSubjectMod subjectMod) {
+        if (StringUtils.isNotBlank(subjectMod.getRealm())) {
+            Realm newRealm = realmDAO.find(subjectMod.getRealm());
+            if (newRealm == null) {
+                LOG.warn("Invalid realm specified: {}, ignoring", subjectMod.getRealm());
+            } else {
+                subject.setRealm(newRealm);
+            }
+        }
+    }
+
     @SuppressWarnings("unchecked")
     protected <T extends Schema> T getSchema(final String schemaName, final Class<T> reference) {
         T result = null;
@@ -190,7 +206,7 @@ abstract class AbstractAttributableDataBinder {
         return derivedSchema;
     }
 
-    protected void fillAttribute(final List<String> values, final AttributableUtil attributableUtil,
+    protected void fillAttribute(final List<String> values, final AttributableUtils attributableUtil,
             final PlainSchema schema, final PlainAttr attr, final SyncopeClientException invalidValues) {
 
         // if schema is multivalue, all values are considered for addition;
@@ -216,22 +232,22 @@ abstract class AbstractAttributableDataBinder {
         }
     }
 
-    private boolean evaluateMandatoryCondition(final AttributableUtil attrUtil, final ExternalResource resource,
+    private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils, final ExternalResource resource,
             final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) {
 
         boolean result = false;
 
-        final List<MappingItem> mappings = MappingUtil.getMatchingMappingItems(
-                attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION), intAttrName, intMappingType);
+        Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems(
+                attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION), intAttrName, intMappingType);
         for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) {
             final MappingItem mapping = itor.next();
-            result |= JexlUtil.evaluateMandatoryCondition(mapping.getMandatoryCondition(), attributable);
+            result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), attributable);
         }
 
         return result;
     }
 
-    private boolean evaluateMandatoryCondition(final AttributableUtil attrUtil,
+    private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils,
             final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) {
 
         boolean result = false;
@@ -242,7 +258,7 @@ abstract class AbstractAttributableDataBinder {
 
                 final ExternalResource resource = itor.next();
                 if (resource.isEnforceMandatoryCondition()) {
-                    result |= evaluateMandatoryCondition(attrUtil, resource, attributable, intAttrName, intMappingType);
+                    result |= evaluateMandatoryCondition(attrUtils, resource, attributable, intAttrName, intMappingType);
                 }
             }
         }
@@ -250,14 +266,14 @@ abstract class AbstractAttributableDataBinder {
         return result;
     }
 
-    private SyncopeClientException checkMandatory(final AttributableUtil attrUtil,
+    private SyncopeClientException checkMandatory(final AttributableUtils attrUtils,
             final Attributable<?, ?, ?> attributable) {
 
         SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
 
         // Check if there is some mandatory schema defined for which no value has been provided
         List<? extends PlainSchema> plainSchemas;
-        switch (attrUtil.getType()) {
+        switch (attrUtils.getType()) {
             case GROUP:
                 plainSchemas = ((Group) attributable).getAttrTemplateSchemas(GPlainAttrTemplate.class);
                 break;
@@ -268,14 +284,14 @@ abstract class AbstractAttributableDataBinder {
 
             case USER:
             default:
-                plainSchemas = plainSchemaDAO.findAll(attrUtil.plainSchemaClass());
+                plainSchemas = plainSchemaDAO.findAll(attrUtils.plainSchemaClass());
         }
         for (PlainSchema schema : plainSchemas) {
             if (attributable.getPlainAttr(schema.getKey()) == null
                     && !schema.isReadonly()
-                    && (JexlUtil.evaluateMandatoryCondition(schema.getMandatoryCondition(), attributable)
-                    || evaluateMandatoryCondition(attrUtil, attributable, schema.getKey(),
-                            attrUtil.plainIntMappingType()))) {
+                    && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), attributable)
+                    || evaluateMandatoryCondition(attrUtils, attributable, schema.getKey(),
+                            attrUtils.plainIntMappingType()))) {
 
                 LOG.error("Mandatory schema " + schema.getKey() + " not provided with values");
 
@@ -284,7 +300,7 @@ abstract class AbstractAttributableDataBinder {
         }
 
         List<? extends DerSchema> derSchemas;
-        switch (attrUtil.getType()) {
+        switch (attrUtils.getType()) {
             case GROUP:
                 derSchemas = ((Group) attributable).getAttrTemplateSchemas(GDerAttrTemplate.class);
                 break;
@@ -295,12 +311,12 @@ abstract class AbstractAttributableDataBinder {
 
             case USER:
             default:
-                derSchemas = derSchemaDAO.findAll(attrUtil.derSchemaClass());
+                derSchemas = derSchemaDAO.findAll(attrUtils.derSchemaClass());
         }
         for (DerSchema derSchema : derSchemas) {
             if (attributable.getDerAttr(derSchema.getKey()) == null
-                    && evaluateMandatoryCondition(attrUtil, attributable, derSchema.getKey(),
-                            attrUtil.derIntMappingType())) {
+                    && evaluateMandatoryCondition(attrUtils, attributable, derSchema.getKey(),
+                            attrUtils.derIntMappingType())) {
 
                 LOG.error("Mandatory derived schema " + derSchema.getKey() + " does not evaluate to any value");
 
@@ -309,7 +325,7 @@ abstract class AbstractAttributableDataBinder {
         }
 
         List<? extends VirSchema> virSchemas;
-        switch (attrUtil.getType()) {
+        switch (attrUtils.getType()) {
             case GROUP:
                 virSchemas = ((Group) attributable).getAttrTemplateSchemas(GVirAttrTemplate.class);
                 break;
@@ -320,13 +336,13 @@ abstract class AbstractAttributableDataBinder {
 
             case USER:
             default:
-                virSchemas = virSchemaDAO.findAll(attrUtil.virSchemaClass());
+                virSchemas = virSchemaDAO.findAll(attrUtils.virSchemaClass());
         }
         for (VirSchema virSchema : virSchemas) {
             if (attributable.getVirAttr(virSchema.getKey()) == null
                     && !virSchema.isReadonly()
-                    && evaluateMandatoryCondition(attrUtil, attributable, virSchema.getKey(),
-                            attrUtil.virIntMappingType())) {
+                    && evaluateMandatoryCondition(attrUtils, attributable, virSchema.getKey(),
+                            attrUtils.virIntMappingType())) {
 
                 LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values");
 
@@ -379,7 +395,7 @@ abstract class AbstractAttributableDataBinder {
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
     protected PropagationByResource fill(final Attributable attributable,
-            final AbstractAttributableMod attributableMod, final AttributableUtil attrUtil,
+            final AbstractAttributableMod attributableMod, final AttributableUtils attrUtils,
             final SyncopeClientCompositeException scce) {
 
         PropagationByResource propByRes = new PropagationByResource();
@@ -420,7 +436,7 @@ abstract class AbstractAttributableDataBinder {
 
         // 3. attributes to be removed
         for (String attributeToBeRemoved : attributableMod.getPlainAttrsToRemove()) {
-            PlainSchema schema = getPlainSchema(attributeToBeRemoved, attrUtil.plainSchemaClass());
+            PlainSchema schema = getPlainSchema(attributeToBeRemoved, attrUtils.plainSchemaClass());
             if (schema != null) {
                 PlainAttr attr = attributable.getPlainAttr(schema.getKey());
                 if (attr == null) {
@@ -437,15 +453,15 @@ abstract class AbstractAttributableDataBinder {
                             || (!attr.getUniqueValue().getStringValue().equals(newValue))) {
 
                         attributable.removePlainAttr(attr);
-                        plainAttrDAO.delete(attr.getKey(), attrUtil.plainAttrClass());
+                        plainAttrDAO.delete(attr.getKey(), attrUtils.plainAttrClass());
                     }
                 }
 
                 if (attributable instanceof Subject) {
                     for (ExternalResource resource : externalResources) {
-                        for (MappingItem mapItem : attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+                        for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
                             if (schema.getKey().equals(mapItem.getIntAttrName())
-                                    && mapItem.getIntMappingType() == attrUtil.plainIntMappingType()) {
+                                    && mapItem.getIntMappingType() == attrUtils.plainIntMappingType()) {
 
                                 propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 
@@ -463,12 +479,12 @@ abstract class AbstractAttributableDataBinder {
 
         // 4. attributes to be updated
         for (AttrMod attributeMod : attributableMod.getPlainAttrsToUpdate()) {
-            PlainSchema schema = getPlainSchema(attributeMod.getSchema(), attrUtil.plainSchemaClass());
+            PlainSchema schema = getPlainSchema(attributeMod.getSchema(), attrUtils.plainSchemaClass());
             PlainAttr attr = null;
             if (schema != null) {
                 attr = attributable.getPlainAttr(schema.getKey());
                 if (attr == null) {
-                    attr = attrUtil.newPlainAttr();
+                    attr = attrUtils.newPlainAttr();
                     setPlainAttrSchema(attributable, attr, schema);
                     if (attr.getSchema() == null) {
                         LOG.debug("Ignoring {} because no valid schema or template was found", attributeMod);
@@ -481,10 +497,10 @@ abstract class AbstractAttributableDataBinder {
 
             if (schema != null && attr != null && attr.getSchema() != null) {
                 if (attributable instanceof Subject) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtil, schema.getKey(),
-                            externalResources, attrUtil.plainIntMappingType(), propByRes);
+                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(),
+                            externalResources, attrUtils.plainIntMappingType(), propByRes);
                 } else if (attributable instanceof Membership) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtil, schema.getKey(),
+                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(),
                             externalResources, IntMappingType.MembershipPlainSchema, propByRes);
                 }
 
@@ -506,7 +522,7 @@ abstract class AbstractAttributableDataBinder {
                     }
                 }
                 for (Long attributeValueId : valuesToBeRemoved) {
-                    plainAttrValueDAO.delete(attributeValueId, attrUtil.plainAttrValueClass());
+                    plainAttrValueDAO.delete(attributeValueId, attrUtils.plainAttrValueClass());
                 }
 
                 // 1.2 add values
@@ -515,7 +531,7 @@ abstract class AbstractAttributableDataBinder {
                         && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
                         || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
 
-                    fillAttribute(attributeMod.getValuesToBeAdded(), attrUtil, schema, attr, invalidValues);
+                    fillAttribute(attributeMod.getValuesToBeAdded(), attrUtils, schema, attr, invalidValues);
                 }
 
                 // if no values are in, the attribute can be safely removed
@@ -533,7 +549,7 @@ abstract class AbstractAttributableDataBinder {
 
         // 5. derived attributes to be removed
         for (String derAttrToBeRemoved : attributableMod.getDerAttrsToRemove()) {
-            DerSchema derSchema = getDerSchema(derAttrToBeRemoved, attrUtil.derSchemaClass());
+            DerSchema derSchema = getDerSchema(derAttrToBeRemoved, attrUtils.derSchemaClass());
             if (derSchema != null) {
                 DerAttr derAttr = attributable.getDerAttr(derSchema.getKey());
                 if (derAttr == null) {
@@ -544,9 +560,9 @@ abstract class AbstractAttributableDataBinder {
 
                 if (attributable instanceof Subject) {
                     for (ExternalResource resource : externalResources) {
-                        for (MappingItem mapItem : attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+                        for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
                             if (derSchema.getKey().equals(mapItem.getIntAttrName())
-                                    && mapItem.getIntMappingType() == attrUtil.derIntMappingType()) {
+                                    && mapItem.getIntMappingType() == attrUtils.derIntMappingType()) {
 
                                 propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 
@@ -567,17 +583,17 @@ abstract class AbstractAttributableDataBinder {
 
         // 6. derived attributes to be added
         for (String derAttrToBeAdded : attributableMod.getDerAttrsToAdd()) {
-            DerSchema derSchema = getDerSchema(derAttrToBeAdded, attrUtil.derSchemaClass());
+            DerSchema derSchema = getDerSchema(derAttrToBeAdded, attrUtils.derSchemaClass());
             if (derSchema != null) {
                 if (attributable instanceof Subject) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtil, derSchema.getKey(),
-                            externalResources, attrUtil.derIntMappingType(), propByRes);
+                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(),
+                            externalResources, attrUtils.derIntMappingType(), propByRes);
                 } else if (attributable instanceof Membership) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtil, derSchema.getKey(),
+                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(),
                             externalResources, IntMappingType.MembershipDerivedSchema, propByRes);
                 }
 
-                DerAttr derAttr = attrUtil.newDerAttr();
+                DerAttr derAttr = attrUtils.newDerAttr();
                 setDerAttrSchema(attributable, derAttr, derSchema);
                 if (derAttr.getSchema() == null) {
                     LOG.debug("Ignoring {} because no valid schema or template was found", derAttrToBeAdded);
@@ -591,13 +607,13 @@ abstract class AbstractAttributableDataBinder {
         LOG.debug("Derived attributes to be added:\n{}", propByRes);
 
         // 7. virtual attributes: for users and groups this is delegated to PropagationManager
-        if (AttributableType.USER != attrUtil.getType() && AttributableType.GROUP != attrUtil.getType()) {
+        if (AttributableType.USER != attrUtils.getType() && AttributableType.GROUP != attrUtils.getType()) {
             virtAttrHander.fillVirtual(attributable, attributableMod.getVirAttrsToRemove(),
-                    attributableMod.getVirAttrsToUpdate(), attrUtil);
+                    attributableMod.getVirAttrsToUpdate(), attrUtils);
         }
 
         // Finally, check if mandatory values are missing
-        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtil, attributable);
+        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable);
         if (!requiredValuesMissing.isEmpty()) {
             scce.addException(requiredValuesMissing);
         }
@@ -612,7 +628,7 @@ abstract class AbstractAttributableDataBinder {
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
     protected void fill(final Attributable attributable, final AbstractAttributableTO attributableTO,
-            final AttributableUtil attrUtil, final SyncopeClientCompositeException scce) {
+            final AttributableUtils attrUtils, final SyncopeClientCompositeException scce) {
 
         // 1. attributes
         SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
@@ -620,18 +636,18 @@ abstract class AbstractAttributableDataBinder {
         // Only consider attributeTO with values
         for (AttrTO attributeTO : attributableTO.getPlainAttrs()) {
             if (attributeTO.getValues() != null && !attributeTO.getValues().isEmpty()) {
-                PlainSchema schema = getPlainSchema(attributeTO.getSchema(), attrUtil.plainSchemaClass());
+                PlainSchema schema = getPlainSchema(attributeTO.getSchema(), attrUtils.plainSchemaClass());
 
                 if (schema != null) {
                     PlainAttr attr = attributable.getPlainAttr(schema.getKey());
                     if (attr == null) {
-                        attr = attrUtil.newPlainAttr();
+                        attr = attrUtils.newPlainAttr();
                         setPlainAttrSchema(attributable, attr, schema);
                     }
                     if (attr.getSchema() == null) {
                         LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
                     } else {
-                        fillAttribute(attributeTO.getValues(), attrUtil, schema, attr, invalidValues);
+                        fillAttribute(attributeTO.getValues(), attrUtils, schema, attr, invalidValues);
 
                         if (!attr.getValuesAsStrings().isEmpty()) {
                             attributable.addPlainAttr(attr);
@@ -648,10 +664,10 @@ abstract class AbstractAttributableDataBinder {
 
         // 2. derived attributes
         for (AttrTO attributeTO : attributableTO.getDerAttrs()) {
-            DerSchema derSchema = getDerSchema(attributeTO.getSchema(), attrUtil.derSchemaClass());
+            DerSchema derSchema = getDerSchema(attributeTO.getSchema(), attrUtils.derSchemaClass());
 
             if (derSchema != null) {
-                DerAttr derAttr = attrUtil.newDerAttr();
+                DerAttr derAttr = attrUtils.newDerAttr();
                 setDerAttrSchema(attributable, derAttr, derSchema);
                 if (derAttr.getSchema() == null) {
                     LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
@@ -663,12 +679,12 @@ abstract class AbstractAttributableDataBinder {
         }
 
         // 3. user and group virtual attributes will be evaluated by the propagation manager only (if needed).
-        if (AttributableType.USER == attrUtil.getType() || AttributableType.GROUP == attrUtil.getType()) {
+        if (AttributableType.USER == attrUtils.getType() || AttributableType.GROUP == attrUtils.getType()) {
             for (AttrTO vattrTO : attributableTO.getVirAttrs()) {
-                VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema(), attrUtil.virSchemaClass());
+                VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema(), attrUtils.virSchemaClass());
 
                 if (virSchema != null) {
-                    VirAttr virAttr = attrUtil.newVirAttr();
+                    VirAttr virAttr = attrUtils.newVirAttr();
                     virtAttrHander.setVirAttrSchema(attributable, virAttr, virSchema);
                     if (virAttr.getSchema() == null) {
                         LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO);
@@ -680,10 +696,19 @@ abstract class AbstractAttributableDataBinder {
             }
         }
 
-        virtAttrHander.fillVirtual(attributable, attributableTO.getVirAttrs(), attrUtil);
+        virtAttrHander.fillVirtual(attributable, attributableTO.getVirAttrs(), attrUtils);
 
-        // 4. resources
+        // 4. realm & resources
         if (attributable instanceof Subject && attributableTO instanceof AbstractSubjectTO) {
+            Realm realm = realmDAO.find(((AbstractSubjectTO) attributableTO).getRealm());
+            if (realm == null) {
+                SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+                noRealm.getElements().add(
+                        "Invalid or null realm specified: " + ((AbstractSubjectTO) attributableTO).getRealm());
+                scce.addException(noRealm);
+            }
+            ((Subject<?, ?, ?>) attributable).setRealm(realm);
+
             for (String resourceName : ((AbstractSubjectTO) attributableTO).getResources()) {
                 ExternalResource resource = resourceDAO.find(resourceName);
 
@@ -693,7 +718,7 @@ abstract class AbstractAttributableDataBinder {
             }
         }
 
-        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtil, attributable);
+        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable);
         if (!requiredValuesMissing.isEmpty()) {
             scce.addException(requiredValuesMissing);
         }
@@ -705,6 +730,7 @@ abstract class AbstractAttributableDataBinder {
     }
 
     protected void fillTO(final AbstractAttributableTO attributableTO,
+            final String realmFullPath,
             final Collection<? extends PlainAttr> attrs,
             final Collection<? extends DerAttr> derAttrs,
             final Collection<? extends VirAttr> virAttrs,
@@ -739,8 +765,10 @@ abstract class AbstractAttributableDataBinder {
         }
 
         if (attributableTO instanceof AbstractSubjectTO) {
+            AbstractSubjectTO subjectTO = AbstractSubjectTO.class.cast(attributableTO);
+            subjectTO.setRealm(realmFullPath);
             for (ExternalResource resource : resources) {
-                ((AbstractSubjectTO) attributableTO).getResources().add(resource.getKey());
+                subjectTO.getResources().add(resource.getKey());
             }
         }
     }
@@ -752,14 +780,14 @@ abstract class AbstractAttributableDataBinder {
             if ((type == AttributableType.USER && resource.getUmapping() != null)
                     || (type == AttributableType.GROUP && resource.getGmapping() != null)) {
 
-                MappingItem accountIdItem = attrUtilFactory.getInstance(type).getAccountIdItem(resource);
+                MappingItem accountIdItem = attrUtilsFactory.getInstance(type).getAccountIdItem(resource);
                 if (accountIdItem == null) {
                     throw new NotFoundException(
                             "AccountId mapping for " + type + " " + subject.getKey()
                             + " on resource '" + resource.getKey() + "'");
                 }
 
-                accountIds.put(resource.getKey(), MappingUtil.getAccountIdValue(subject, resource, accountIdItem));
+                accountIds.put(resource.getKey(), MappingUtils.getAccountIdValue(subject, resource, accountIdItem));
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index f1d9020..5e2dc1b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -40,7 +40,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder
         final ConfTO confTO = new ConfTO();
         confTO.setKey(conf.getKey());
 
-        fillTO(confTO, conf.getPlainAttrs(),
+        fillTO(confTO, null, conf.getPlainAttrs(),
                 conf.getDerAttrs(), conf.getVirAttrs(), Collections.<ExternalResource>emptySet());
 
         return confTO;
@@ -66,7 +66,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder
 
             CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class);
             attr.setSchema(schema);
-            fillAttribute(attributeTO.getValues(), attrUtilFactory.getInstance(AttributableType.CONFIGURATION),
+            fillAttribute(attributeTO.getValues(), attrUtilsFactory.getInstance(AttributableType.CONFIGURATION),
                     schema, attr, invalidValues);
 
             if (!invalidValues.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index fbb687e..3666d8f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -22,8 +22,9 @@ import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
@@ -34,7 +35,7 @@ import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtil;
+import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
 import org.identityconnectors.framework.api.ConfigurationProperties;
 import org.identityconnectors.framework.api.ConfigurationProperty;
 import org.identityconnectors.framework.impl.api.ConfigurationPropertyImpl;
@@ -116,7 +117,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
         }
         if (connInstanceTO.getPoolConf() != null) {
             connInstance.setPoolConf(
-                    ConnPoolConfUtil.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
+                    ConnPoolConfUtils.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
         }
 
         // Throw exception if there is at least one element set
@@ -171,7 +172,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
             connInstance.setPoolConf(null);
         } else {
             connInstance.setPoolConf(
-                    ConnPoolConfUtil.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
+                    ConnPoolConfUtils.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
         }
 
         if (!sce.isEmpty()) {
@@ -211,29 +212,31 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
         ConnInstanceTO connInstanceTO = new ConnInstanceTO();
         connInstanceTO.setKey(connInstance.getKey() == null ? 0L : connInstance.getKey());
 
-        // retrieve the ConfigurationProperties
-        ConfigurationProperties properties = connIdBundleManager.getConfigurationProperties(
-                connIdBundleManager.getConnectorInfo(connInstance.getLocation(),
-                        connInstance.getBundleName(), connInstance.getVersion(), connInstance.getConnectorName()));
-
         BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
 
-        final Map<String, ConnConfProperty> connInstanceToConfMap = connInstanceTO.getConfigurationMap();
-
-        for (String propName : properties.getPropertyNames()) {
+        // refresh stored properties in the given connInstance with direct information from underlying connector
+        ConfigurationProperties properties =
+                connIdBundleManager.getConfigurationProperties(connIdBundleManager.getConnectorInfo(connInstance));
+        for (final String propName : properties.getPropertyNames()) {
             ConnConfPropSchema schema = buildConnConfPropSchema(properties.getProperty(propName));
 
-            ConnConfProperty property;
-            if (connInstanceToConfMap.containsKey(propName)) {
-                property = connInstanceToConfMap.get(propName);
-            } else {
+            ConnConfProperty property = CollectionUtils.find(connInstanceTO.getConfiguration(),
+                    new Predicate<ConnConfProperty>() {
+
+                        @Override
+                        public boolean evaluate(final ConnConfProperty candidate) {
+                            return propName.equals(candidate.getSchema().getName());
+                        }
+                    });
+            if (property == null) {
                 property = new ConnConfProperty();
                 connInstanceTO.getConfiguration().add(property);
             }
-
+            
             property.setSchema(schema);
         }
 
+        // pool configuration
         if (connInstance.getPoolConf() != null) {
             ConnPoolConfTO poolConf = new ConnPoolConfTO();
             BeanUtils.copyProperties(connInstance.getPoolConf(), poolConf);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index 4a5ed5f..6cadc9d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import static org.apache.syncope.core.provisioning.java.data.AbstractAttributableDataBinder.LOG;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -28,11 +30,7 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Schema;
 import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
@@ -40,20 +38,17 @@ import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTempl
 import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.ConnObjectUtil;
+import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -63,10 +58,7 @@ import org.springframework.transaction.annotation.Transactional;
 public class GroupDataBinderImpl extends AbstractAttributableDataBinder implements GroupDataBinder {
 
     @Autowired
-    private ConnObjectUtil connObjectUtil;
-
-    @Autowired
-    private EntitlementDAO entitlementDAO;
+    private ConnObjectUtils connObjectUtils;
 
     private <T extends AttrTemplate<S>, S extends Schema> void setAttrTemplates(
             final Group group, final List<String> schemaNames,
@@ -99,20 +91,9 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
 
     @Override
     public Group create(final Group group, final GroupTO groupTO) {
-        group.setInheritOwner(groupTO.isInheritOwner());
-
-        group.setInheritPlainAttrs(groupTO.isInheritPlainAttrs());
-        group.setInheritDerAttrs(groupTO.isInheritDerAttrs());
-        group.setInheritVirAttrs(groupTO.isInheritVirAttrs());
-
-        group.setInheritTemplates(groupTO.isInheritTemplates());
-
-        group.setInheritPasswordPolicy(groupTO.isInheritPasswordPolicy());
-        group.setInheritAccountPolicy(groupTO.isInheritAccountPolicy());
-
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
-        // name and parent
+        // name
         SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroups);
         if (groupTO.getName() == null) {
             LOG.error("No name specified for this group");
@@ -121,26 +102,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         } else {
             group.setName(groupTO.getName());
         }
-        Long parentGroupKey = null;
-        if (groupTO.getParent() != 0) {
-            Group parentGroup = groupDAO.find(groupTO.getParent());
-            if (parentGroup == null) {
-                LOG.error("Could not find group with id " + groupTO.getParent());
-
-                invalidGroups.getElements().add(String.valueOf(groupTO.getParent()));
-                scce.addException(invalidGroups);
-            } else {
-                group.setParent(parentGroup);
-                parentGroupKey = group.getParent().getKey();
-            }
-        }
-
-        Group otherGroup = groupDAO.find(groupTO.getName(), parentGroupKey);
-        if (otherGroup != null) {
-            LOG.error("Another group exists with the same name and the same parent group: " + otherGroup);
-
-            invalidGroups.getElements().add(groupTO.getName());
-        }
 
         // attribute templates
         setAttrTemplates(group, groupTO.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class);
@@ -151,17 +112,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         setAttrTemplates(group, groupTO.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
 
         // attributes, derived attributes, virtual attributes and resources
-        fill(group, groupTO, attrUtilFactory.getInstance(AttributableType.GROUP), scce);
-
-        // entitlements
-        for (String entitlementName : groupTO.getEntitlements()) {
-            Entitlement entitlement = entitlementDAO.find(entitlementName);
-            if (entitlement == null) {
-                LOG.warn("Ignoring invalid entitlement {}", entitlementName);
-            } else {
-                group.addEntitlement(entitlement);
-            }
-        }
+        fill(group, groupTO, attrUtilsFactory.getInstance(AttributableType.GROUP), scce);
 
         // owner
         if (groupTO.getUserOwner() != null) {
@@ -181,19 +132,14 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             }
         }
 
-        // policies
-        if (groupTO.getPasswordPolicy() != null) {
-            group.setPasswordPolicy((PasswordPolicy) policyDAO.find(groupTO.getPasswordPolicy()));
-        }
-        if (groupTO.getAccountPolicy() != null) {
-            group.setAccountPolicy((AccountPolicy) policyDAO.find(groupTO.getAccountPolicy()));
-        }
-
         return group;
     }
 
     @Override
-    public PropagationByResource update(final Group group, final GroupMod groupMod) {
+    public PropagationByResource update(final Group toBeUpdated, final GroupMod groupMod) {
+        // Re-merge any pending change from workflow tasks
+        Group group = groupDAO.save(toBeUpdated);
+
         PropagationByResource propByRes = new PropagationByResource();
 
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
@@ -201,72 +147,24 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         // fetch account ids before update
         Map<String, String> oldAccountIds = getAccountIds(group, AttributableType.GROUP);
 
+        // realm
+        setRealm(group, groupMod);
         // name
-        SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroups);
-        if (groupMod.getName() != null) {
-            Group otherGroup = groupDAO.find(groupMod.getName(),
-                    group.getParent() == null ? null : group.getParent().getKey());
-            if (otherGroup == null || group.equals(otherGroup)) {
-                if (!groupMod.getName().equals(group.getName())) {
-                    propByRes.addAll(ResourceOperation.UPDATE, group.getResourceNames());
-
-                    group.setName(groupMod.getName());
-                }
-            } else {
-                LOG.error("Another group exists with the same name and the same parent group: " + otherGroup);
-
-                invalidGroups.getElements().add(groupMod.getName());
-                scce.addException(invalidGroups);
-            }
-        }
-
-        if (groupMod.getInheritOwner() != null) {
-            group.setInheritOwner(groupMod.getInheritOwner());
-        }
-
-        if (groupMod.getInheritTemplates() != null) {
-            group.setInheritTemplates(groupMod.getInheritTemplates());
-        }
-
-        if (groupMod.getInheritPlainAttrs() != null) {
-            group.setInheritPlainAttrs(groupMod.getInheritPlainAttrs());
-        }
-        if (groupMod.getInheritDerAttrs() != null) {
-            group.setInheritDerAttrs(groupMod.getInheritDerAttrs());
-        }
-        if (groupMod.getInheritVirAttrs() != null) {
-            group.setInheritVirAttrs(groupMod.getInheritVirAttrs());
-        }
+        if (groupMod.getName() != null && !groupMod.getName().equals(group.getName())) {
+            propByRes.addAll(ResourceOperation.UPDATE, group.getResourceNames());
 
-        if (groupMod.getInheritPasswordPolicy() != null) {
-            group.setInheritPasswordPolicy(groupMod.getInheritPasswordPolicy());
-        }
-        if (groupMod.getInheritAccountPolicy() != null) {
-            group.setInheritAccountPolicy(groupMod.getInheritAccountPolicy());
-        }
-
-        // entitlements
-        if (groupMod.isModEntitlements()) {
-            group.getEntitlements().clear();
-            for (String entitlementName : groupMod.getEntitlements()) {
-                Entitlement entitlement = entitlementDAO.find(entitlementName);
-                if (entitlement == null) {
-                    LOG.warn("Ignoring invalid entitlement {}", entitlementName);
-                } else {
-                    group.addEntitlement(entitlement);
-                }
-            }
+            group.setName(groupMod.getName());
         }
 
         // attribute templates
-        if (groupMod.isModRAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getRPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class);
+        if (groupMod.isModGAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class);
         }
-        if (groupMod.isModRDerAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getRDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class);
+        if (groupMod.isModGDerAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getGDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class);
         }
-        if (groupMod.isModRVirAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getRVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class);
+        if (groupMod.isModGVirAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getGVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class);
         }
         if (groupMod.isModMAttrTemplates()) {
             setAttrTemplates(group, groupMod.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class);
@@ -278,18 +176,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             setAttrTemplates(group, groupMod.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
         }
 
-        // policies
-        if (groupMod.getPasswordPolicy() != null) {
-            group.setPasswordPolicy(groupMod.getPasswordPolicy().getKey() == null
-                    ? null
-                    : (PasswordPolicy) policyDAO.find(groupMod.getPasswordPolicy().getKey()));
-        }
-        if (groupMod.getAccountPolicy() != null) {
-            group.setAccountPolicy(groupMod.getAccountPolicy().getKey() == null
-                    ? null
-                    : (AccountPolicy) policyDAO.find(groupMod.getAccountPolicy().getKey()));
-        }
-
         // owner
         if (groupMod.getUserOwner() != null) {
             group.setUserOwner(groupMod.getUserOwner().getKey() == null
@@ -303,7 +189,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         }
 
         // attributes, derived attributes, virtual attributes and resources
-        propByRes.merge(fill(group, groupMod, attrUtilFactory.getInstance(AttributableType.GROUP), scce));
+        propByRes.merge(fill(group, groupMod, attrUtilsFactory.getInstance(AttributableType.GROUP), scce));
 
         // check if some account id was changed by the update above
         Map<String, String> newAccountIds = getAccountIds(group, AttributableType.GROUP);
@@ -323,7 +209,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
     @Transactional(readOnly = true)
     @Override
     public GroupTO getGroupTO(final Group group) {
-        connObjectUtil.retrieveVirAttrValues(group, attrUtilFactory.getInstance(AttributableType.GROUP));
+        connObjectUtils.retrieveVirAttrValues(group, attrUtilsFactory.getInstance(AttributableType.GROUP));
 
         GroupTO groupTO = new GroupTO();
 
@@ -336,21 +222,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         groupTO.setKey(group.getKey());
         groupTO.setName(group.getName());
 
-        groupTO.setInheritOwner(group.isInheritOwner());
-
-        groupTO.setInheritTemplates(group.isInheritTemplates());
-
-        groupTO.setInheritPlainAttrs(group.isInheritPlainAttrs());
-        groupTO.setInheritDerAttrs(group.isInheritDerAttrs());
-        groupTO.setInheritVirAttrs(group.isInheritVirAttrs());
-
-        groupTO.setInheritPasswordPolicy(group.isInheritPasswordPolicy());
-        groupTO.setInheritAccountPolicy(group.isInheritAccountPolicy());
-
-        if (group.getParent() != null) {
-            groupTO.setParent(group.getParent().getKey());
-        }
-
         if (group.getUserOwner() != null) {
             groupTO.setUserOwner(group.getUserOwner().getKey());
         }
@@ -358,48 +229,28 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             groupTO.setGroupOwner(group.getGroupOwner().getKey());
         }
 
-        // -------------------------
-        // Retrieve all [derived/virtual] attributes (inherited and not)
-        // -------------------------        
-        final List<? extends GPlainAttr> allAttributes = group.findLastInheritedAncestorPlainAttrs();
-
-        final List<? extends GDerAttr> allDerAttributes = group.findLastInheritedAncestorDerAttrs();
-
-        final List<? extends GVirAttr> allVirAttributes = group.findLastInheritedAncestorVirAttrs();
-        // -------------------------
-
-        fillTO(groupTO, allAttributes, allDerAttributes, allVirAttributes, group.getResources());
+        fillTO(groupTO, group.getRealm().getFullPath(),
+                group.getPlainAttrs(), group.getDerAttrs(), group.getVirAttrs(), group.getResources());
 
-        for (Entitlement entitlement : group.getEntitlements()) {
-            groupTO.getEntitlements().add(entitlement.getKey());
-        }
-
-        for (GPlainAttrTemplate template : group.findInheritedTemplates(GPlainAttrTemplate.class)) {
+        for (GPlainAttrTemplate template : group.getAttrTemplates(GPlainAttrTemplate.class)) {
             groupTO.getGPlainAttrTemplates().add(template.getSchema().getKey());
         }
-        for (GDerAttrTemplate template : group.findInheritedTemplates(GDerAttrTemplate.class)) {
+        for (GDerAttrTemplate template : group.getAttrTemplates(GDerAttrTemplate.class)) {
             groupTO.getGDerAttrTemplates().add(template.getSchema().getKey());
         }
-        for (GVirAttrTemplate template : group.findInheritedTemplates(GVirAttrTemplate.class)) {
+        for (GVirAttrTemplate template : group.getAttrTemplates(GVirAttrTemplate.class)) {
             groupTO.getGVirAttrTemplates().add(template.getSchema().getKey());
         }
-        for (MPlainAttrTemplate template : group.findInheritedTemplates(MPlainAttrTemplate.class)) {
+        for (MPlainAttrTemplate template : group.getAttrTemplates(MPlainAttrTemplate.class)) {
             groupTO.getMPlainAttrTemplates().add(template.getSchema().getKey());
         }
-        for (MDerAttrTemplate template : group.findInheritedTemplates(MDerAttrTemplate.class)) {
+        for (MDerAttrTemplate template : group.getAttrTemplates(MDerAttrTemplate.class)) {
             groupTO.getMDerAttrTemplates().add(template.getSchema().getKey());
         }
-        for (MVirAttrTemplate template : group.findInheritedTemplates(MVirAttrTemplate.class)) {
+        for (MVirAttrTemplate template : group.getAttrTemplates(MVirAttrTemplate.class)) {
             groupTO.getMVirAttrTemplates().add(template.getSchema().getKey());
         }
 
-        groupTO.setPasswordPolicy(group.getPasswordPolicy() == null
-                ? null
-                : group.getPasswordPolicy().getKey());
-        groupTO.setAccountPolicy(group.getAccountPolicy() == null
-                ? null
-                : group.getAccountPolicy().getKey());
-
         return groupTO;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index 1f0e308..3800adb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -29,14 +29,14 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,40 +54,31 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
-    private GroupDAO groupDAO;
+    private RealmDAO realmDAO;
 
     @Autowired
     private EntityFactory entityFactory;
 
-    /**
-     * Get policy TO from policy bean.
-     *
-     * @param policy bean.
-     * @return policy TO.
-     */
     @SuppressWarnings("unchecked")
     @Override
     public <T extends AbstractPolicyTO> T getPolicyTO(final Policy policy) {
         final T policyTO;
 
         switch (policy.getType()) {
-            case GLOBAL_PASSWORD:
             case PASSWORD:
-                policyTO = (T) new PasswordPolicyTO(policy.getType().isGlobal());
+                policyTO = (T) new PasswordPolicyTO();
                 ((PasswordPolicyTO) policyTO).setSpecification(policy.getSpecification(PasswordPolicySpec.class));
                 break;
 
-            case GLOBAL_ACCOUNT:
             case ACCOUNT:
-                policyTO = (T) new AccountPolicyTO(policy.getType().isGlobal());
+                policyTO = (T) new AccountPolicyTO();
                 ((AccountPolicyTO) policyTO).setSpecification(policy.getSpecification(AccountPolicySpec.class));
                 ((AccountPolicyTO) policyTO).getResources().addAll(((AccountPolicy) policy).getResourceNames());
                 break;
 
-            case GLOBAL_SYNC:
             case SYNC:
             default:
-                policyTO = (T) new SyncPolicyTO(policy.getType().isGlobal());
+                policyTO = (T) new SyncPolicyTO();
                 ((SyncPolicyTO) policyTO).setSpecification(policy.getSpecification(SyncPolicySpec.class));
         }
 
@@ -97,18 +88,8 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
         for (ExternalResource resource : resourceDAO.findByPolicy(policy)) {
             policyTO.getUsedByResources().add(resource.getKey());
         }
-        if (policy.getType().isGlobal()) {
-            for (ExternalResource resource : resourceDAO.findWithoutPolicy(policy.getType())) {
-                policyTO.getUsedByResources().add(resource.getKey());
-            }
-        }
-        for (Group group : groupDAO.findByPolicy(policy)) {
-            policyTO.getUsedByGroups().add(group.getKey());
-        }
-        if (policy.getType().isGlobal()) {
-            for (Group group : groupDAO.findWithoutPolicy(policy.getType())) {
-                policyTO.getUsedByGroups().add(group.getKey());
-            }
+        for (Realm realm : realmDAO.findByPolicy(policy)) {
+            policyTO.getUsedByRealms().add(realm.getFullPath());
         }
 
         return policyTO;
@@ -133,26 +114,24 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
         }
 
         switch (policyTO.getType()) {
-            case GLOBAL_PASSWORD:
             case PASSWORD:
                 if (!(policyTO instanceof PasswordPolicyTO)) {
                     throw new ClassCastException("Expected " + PasswordPolicyTO.class.getName()
                             + ", found " + policyTO.getClass().getName());
                 }
                 if (policy == null) {
-                    policy = (T) entityFactory.newPolicy(PasswordPolicy.class, policyTO.getType().isGlobal());
+                    policy = (T) entityFactory.newEntity(PasswordPolicy.class);
                 }
                 policy.setSpecification(((PasswordPolicyTO) policyTO).getSpecification());
                 break;
 
-            case GLOBAL_ACCOUNT:
             case ACCOUNT:
                 if (!(policyTO instanceof AccountPolicyTO)) {
                     throw new ClassCastException("Expected " + AccountPolicyTO.class.getName()
                             + ", found " + policyTO.getClass().getName());
                 }
                 if (policy == null) {
-                    policy = (T) entityFactory.newPolicy(AccountPolicy.class, policyTO.getType().isGlobal());
+                    policy = (T) entityFactory.newEntity(AccountPolicy.class);
                 }
                 policy.setSpecification(((AccountPolicyTO) policyTO).getSpecification());
 
@@ -169,7 +148,6 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
                 }
                 break;
 
-            case GLOBAL_SYNC:
             case SYNC:
             default:
                 if (!(policyTO instanceof SyncPolicyTO)) {
@@ -177,7 +155,7 @@ public class PolicyDataBinderImpl implements PolicyDataBinder {
                             + ", found " + policyTO.getClass().getName());
                 }
                 if (policy == null) {
-                    policy = (T) entityFactory.newPolicy(SyncPolicy.class, policyTO.getType().isGlobal());
+                    policy = (T) entityFactory.newEntity(SyncPolicy.class);
                 }
                 policy.setSpecification(((SyncPolicyTO) policyTO).getSpecification());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index 05a0648..cf1339e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -46,7 +46,7 @@ import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
-import org.apache.syncope.core.misc.jexl.JexlUtil;
+import org.apache.syncope.core.misc.jexl.JexlUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.syncope.core.misc.spring.BeanUtils;
@@ -204,13 +204,12 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         }
 
         // no mandatory condition implies mandatory condition false
-        if (!JexlUtil.isExpressionValid(itemTO.getMandatoryCondition() == null
+        if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
                 ? "false" : itemTO.getMandatoryCondition())) {
 
             SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
                     ClientExceptionType.InvalidValues);
             invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
-
             scce.addException(invalidMandatoryCondition);
         }
 
@@ -234,6 +233,24 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         return connRegistry.getOverriddenConnInstance(connInstanceClone, resourceTO.getConnConfProperties());
     }
 
+    private void populateMappingTO(final Mapping<?> mapping, final MappingTO mappingTO) {
+        mappingTO.setAccountLink(mapping.getAccountLink());
+
+        for (MappingItem item : mapping.getItems()) {
+            MappingItemTO itemTO = new MappingItemTO();
+            itemTO.setKey(item.getKey());
+            BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+
+            if (itemTO.isAccountid()) {
+                mappingTO.setAccountIdItem(itemTO);
+            } else if (itemTO.isPassword()) {
+                mappingTO.setPasswordItem(itemTO);
+            } else {
+                mappingTO.addItem(itemTO);
+            }
+        }
+    }
+
     @Override
     public ResourceTO getResourceTO(final ExternalResource resource) {
         if (resource == null) {
@@ -302,48 +319,4 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         return resourceTO;
     }
-
-    private void populateMappingTO(final Mapping<?> mapping, final MappingTO mappingTO) {
-        mappingTO.setAccountLink(mapping.getAccountLink());
-
-        for (MappingItemTO itemTO : getMappingItemTOs(mapping.getItems())) {
-            if (itemTO.isAccountid()) {
-                mappingTO.setAccountIdItem(itemTO);
-            } else if (itemTO.isPassword()) {
-                mappingTO.setPasswordItem(itemTO);
-            } else {
-                mappingTO.addItem(itemTO);
-            }
-        }
-    }
-
-    private Set<MappingItemTO> getMappingItemTOs(final Collection<? extends MappingItem> items) {
-        Set<MappingItemTO> mappingTOs = new HashSet<>();
-        for (MappingItem item : items) {
-            LOG.debug("Asking for TO for {}", item);
-            mappingTOs.add(getMappingItemTO(item));
-        }
-
-        LOG.debug("Collected TOs: {}", mappingTOs);
-
-        return mappingTOs;
-    }
-
-    private MappingItemTO getMappingItemTO(final MappingItem item) {
-        if (item == null) {
-            LOG.error("Provided null mapping");
-
-            return null;
-        }
-
-        MappingItemTO itemTO = new MappingItemTO();
-
-        BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
-
-        itemTO.setKey(item.getKey());
-
-        LOG.debug("Obtained SchemaMappingTO {}", itemTO);
-
-        return itemTO;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
index 842bf35..de07e3b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import org.apache.commons.collections4.Closure;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.to.RoleTO;
@@ -53,24 +52,19 @@ public class RoleDataBinderImpl implements RoleDataBinder {
     @Override
     public void update(final Role role, final RoleTO roleTO) {
         role.setName(roleTO.getName());
-        role.setCriteria(roleTO.getCriteria());
 
         role.getEntitlements().clear();
         role.getEntitlements().addAll(roleTO.getEntitlements());
 
         role.getRealms().clear();
-        CollectionUtils.forAllDo(roleTO.getRealms(), new Closure<String>() {
-
-            @Override
-            public void execute(final String realmFullPath) {
-                Realm realm = realmDAO.find(realmFullPath);
-                if (realm == null) {
-                    LOG.warn("Invalid realm full path {}, ignoring", realmFullPath);
-                } else {
-                    role.addRealm(realm);
-                }
+        for (String realmFullPath : roleTO.getRealms()) {
+            Realm realm = realmDAO.find(realmFullPath);
+            if (realm == null) {
+                LOG.warn("Invalid realm full path {}, ignoring", realmFullPath);
+            } else {
+                role.addRealm(realm);
             }
-        });
+        }
     }
 
     @Override
@@ -79,7 +73,6 @@ public class RoleDataBinderImpl implements RoleDataBinder {
 
         roleTO.setKey(role.getKey());
         roleTO.setName(role.getName());
-        roleTO.setCriteria(role.getCriteria());
         roleTO.getEntitlements().addAll(role.getEntitlements());
 
         CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index 7167922..0a34e61 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -28,13 +28,13 @@ import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtil;
+import org.apache.syncope.core.misc.jexl.JexlUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -46,7 +46,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
 
     // --------------- PLAIN -----------------
     private <T extends PlainSchema> void fill(final T schema, final PlainSchemaTO schemaTO) {
-        if (!JexlUtil.isExpressionValid(schemaTO.getMandatoryCondition())) {
+        if (!JexlUtils.isExpressionValid(schemaTO.getMandatoryCondition())) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidValues);
             sce.getElements().add(schemaTO.getMandatoryCondition());
             throw sce;
@@ -62,7 +62,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
 
     @Override
     public <T extends PlainSchema> void update(final PlainSchemaTO schemaTO, final T schema,
-            final AttributableUtil attributableUtil) {
+            final AttributableUtils attributableUtil) {
 
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
@@ -91,7 +91,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
 
     @Override
     public <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(
-            final T schema, final AttributableUtil attributableUtil) {
+            final T schema, final AttributableUtils attributableUtil) {
 
         PlainSchemaTO schemaTO = new PlainSchemaTO();
         BeanUtils.copyProperties(schema, schemaTO);
@@ -109,7 +109,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
             requiredValuesMissing.getElements().add("expression");
 
             scce.addException(requiredValuesMissing);
-        } else if (!JexlUtil.isExpressionValid(derSchemaTO.getExpression())) {
+        } else if (!JexlUtils.isExpressionValid(derSchemaTO.getExpression())) {
             SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidValues);
             e.getElements().add(derSchemaTO.getExpression());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 8a1076b..9fe733e 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
@@ -49,10 +49,11 @@ import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.task.TaskUtil;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtil;
+import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -72,11 +73,14 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     private static final Logger LOG = LoggerFactory.getLogger(TaskDataBinder.class);
 
     private static final String[] IGNORE_TASK_PROPERTIES = {
-        "executions", "resource", "matchingRule", "unmatchingRule" };
+        "destinationRealm", "executions", "resource", "matchingRule", "unmatchingRule" };
 
     private static final String[] IGNORE_TASK_EXECUTION_PROPERTIES = { "key", "task" };
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
@@ -87,21 +91,19 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
     private void checkJexl(final AbstractAttributableTO attributableTO, final SyncopeClientException sce) {
         for (AttrTO attrTO : attributableTO.getPlainAttrs()) {
-            if (!attrTO.getValues().isEmpty() && !JexlUtil.isExpressionValid(attrTO.getValues().get(0))) {
+            if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
                 sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
             }
         }
 
         for (AttrTO attrTO : attributableTO.getVirAttrs()) {
-            if (!attrTO.getValues().isEmpty() && !JexlUtil.isExpressionValid(attrTO.getValues().get(0))) {
+            if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
                 sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
             }
         }
     }
 
     private void fill(final ProvisioningTask task, final AbstractProvisioningTaskTO taskTO) {
-        SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSyncTask);
-
         if (task instanceof PushTask && taskTO instanceof PushTaskTO) {
             final PushTask pushTask = (PushTask) task;
             final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
@@ -119,23 +121,26 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             final SyncTask syncTask = (SyncTask) task;
             final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO;
 
+            syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
+
             syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
                     ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
 
             syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
                     ? UnmatchingRule.PROVISION : syncTaskTO.getUnmatchingRule());
 
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSyncTask);
             // 1. validate JEXL expressions in user and group templates
             if (syncTaskTO.getUserTemplate() != null) {
                 UserTO template = syncTaskTO.getUserTemplate();
 
                 if (StringUtils.isNotBlank(template.getUsername())
-                        && !JexlUtil.isExpressionValid(template.getUsername())) {
+                        && !JexlUtils.isExpressionValid(template.getUsername())) {
 
                     sce.getElements().add("Invalid JEXL: " + template.getUsername());
                 }
                 if (StringUtils.isNotBlank(template.getPassword())
-                        && !JexlUtil.isExpressionValid(template.getPassword())) {
+                        && !JexlUtils.isExpressionValid(template.getPassword())) {
 
                     sce.getElements().add("Invalid JEXL: " + template.getPassword());
                 }
@@ -149,7 +154,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             if (syncTaskTO.getGroupTemplate() != null) {
                 GroupTO template = syncTaskTO.getGroupTemplate();
 
-                if (StringUtils.isNotBlank(template.getName()) && !JexlUtil.isExpressionValid(template.getName())) {
+                if (StringUtils.isNotBlank(template.getName()) && !JexlUtils.isExpressionValid(template.getName())) {
                     sce.getElements().add("Invalid JEXL: " + template.getName());
                 }
 
@@ -176,20 +181,20 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     }
 
     @Override
-    public SchedTask createSchedTask(final SchedTaskTO taskTO, final TaskUtil taskUtil) {
-        final Class<? extends AbstractTaskTO> taskTOClass = taskUtil.taskTOClass();
+    public SchedTask createSchedTask(final SchedTaskTO taskTO, final TaskUtils taskUtils) {
+        final Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
 
         if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
             throw new IllegalArgumentException(
-                    String.format("taskUtil is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
+                    String.format("taskUtils is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
         }
 
-        SchedTask task = taskUtil.newTask();
+        SchedTask task = taskUtils.newTask();
         task.setCronExpression(taskTO.getCronExpression());
         task.setName(taskTO.getName());
         task.setDescription(taskTO.getDescription());
 
-        if (taskUtil.getType() == TaskType.SCHEDULED) {
+        if (taskUtils.getType() == TaskType.SCHEDULED) {
             task.setJobClassName(taskTO.getJobClassName());
         } else if (taskTO instanceof AbstractProvisioningTaskTO) {
             final AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
@@ -207,18 +212,18 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     }
 
     @Override
-    public void updateSchedTask(final SchedTask task, final SchedTaskTO taskTO, final TaskUtil taskUtil) {
-        Class<? extends Task> taskClass = taskUtil.taskClass();
-        Class<? extends AbstractTaskTO> taskTOClass = taskUtil.taskTOClass();
+    public void updateSchedTask(final SchedTask task, final SchedTaskTO taskTO, final TaskUtils taskUtils) {
+        Class<? extends Task> taskClass = taskUtils.taskClass();
+        Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
 
         if (taskClass == null || !taskClass.isAssignableFrom(task.getClass())) {
             throw new IllegalArgumentException(
-                    String.format("taskUtil is type %s but task is not: %s", taskClass, task.getClass()));
+                    String.format("taskUtils is type %s but task is not: %s", taskClass, task.getClass()));
         }
 
         if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
             throw new IllegalArgumentException(
-                    String.format("taskUtil is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
+                    String.format("taskUtils is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
         }
 
         task.setCronExpression(taskTO.getCronExpression());
@@ -267,12 +272,12 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     }
 
     @Override
-    public <T extends AbstractTaskTO> T getTaskTO(final Task task, final TaskUtil taskUtil) {
-        T taskTO = taskUtil.newTaskTO();
+    public <T extends AbstractTaskTO> T getTaskTO(final Task task, final TaskUtils taskUtils) {
+        T taskTO = taskUtils.newTaskTO();
         BeanUtils.copyProperties(task, taskTO, IGNORE_TASK_PROPERTIES);
 
         TaskExec latestExec = taskExecDAO.findLatestStarted(task);
-        taskTO.setLatestExecStatus(latestExec == null ? "" : latestExec.getStatus());
+        taskTO.setLatestExecStatus(latestExec == null ? StringUtils.EMPTY : latestExec.getStatus());
         taskTO.setStartDate(latestExec == null ? null : latestExec.getStartDate());
         taskTO.setEndDate(latestExec == null ? null : latestExec.getEndDate());
 
@@ -280,10 +285,10 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             taskTO.getExecutions().add(getTaskExecTO(execution));
         }
 
-        switch (taskUtil.getType()) {
+        switch (taskUtils.getType()) {
             case PROPAGATION:
                 if (!(task instanceof PropagationTask)) {
-                    throw new IllegalArgumentException("taskUtil is type Propagation but task is not PropagationTask: "
+                    throw new IllegalArgumentException("taskUtils is type Propagation but task is not PropagationTask: "
                             + task.getClass().getName());
                 }
                 ((PropagationTaskTO) taskTO).setResource(((PropagationTask) task).getResource().getKey());
@@ -291,7 +296,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             case SCHEDULED:
                 if (!(task instanceof SchedTask)) {
-                    throw new IllegalArgumentException("taskUtil is type Sched but task is not SchedTask: "
+                    throw new IllegalArgumentException("taskUtils is type Sched but task is not SchedTask: "
                             + task.getClass().getName());
                 }
                 setExecTime((SchedTaskTO) taskTO, task);
@@ -301,12 +306,13 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             case SYNCHRONIZATION:
                 if (!(task instanceof SyncTask)) {
-                    throw new IllegalArgumentException("taskUtil is type Sync but task is not SyncTask: "
+                    throw new IllegalArgumentException("taskUtils is type Sync but task is not SyncTask: "
                             + task.getClass().getName());
                 }
                 setExecTime((SchedTaskTO) taskTO, task);
                 ((SyncTaskTO) taskTO).setName(((SyncTask) task).getName());
                 ((SyncTaskTO) taskTO).setDescription(((SyncTask) task).getDescription());
+                ((SyncTaskTO) taskTO).setDestinationRealm(((SyncTask) task).getDestinatioRealm().getFullPath());
                 ((SyncTaskTO) taskTO).setResource(((SyncTask) task).getResource().getKey());
                 ((SyncTaskTO) taskTO).setMatchingRule(((SyncTask) task).getMatchingRule() == null
                         ? MatchingRule.UPDATE : ((SyncTask) task).getMatchingRule());
@@ -316,7 +322,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             case PUSH:
                 if (!(task instanceof PushTask)) {
-                    throw new IllegalArgumentException("taskUtil is type Push but task is not PushTask: "
+                    throw new IllegalArgumentException("taskUtils is type Push but task is not PushTask: "
                             + task.getClass().getName());
                 }
                 setExecTime((SchedTaskTO) taskTO, task);