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 2017/07/18 10:22:44 UTC

[01/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Repository: syncope
Updated Branches:
  refs/heads/2_0_X d540e511d -> e21971bf5
  refs/heads/master 3faef350f -> eebca673e


http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
index 81f94b9..4209734 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
@@ -53,7 +53,7 @@ import org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddress
 import org.apache.syncope.core.persistence.jpa.dao.DefaultAccountRule;
 import org.apache.syncope.core.persistence.jpa.dao.DefaultPasswordRule;
 import org.apache.syncope.core.provisioning.java.DefaultLogicActions;
-import org.apache.syncope.core.provisioning.java.data.DefaultMappingItemTransformer;
+import org.apache.syncope.core.provisioning.java.data.DefaultItemTransformer;
 import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
 import org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions;
 import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
@@ -99,9 +99,9 @@ public class ITImplementationLookup implements ImplementationLookup {
             put(Type.PASSWORD_RULE_CONF, classNames);
 
             classNames = new HashSet<>();
-            classNames.add(PrefixMappingItemTransformer.class.getName());
-            classNames.add(DefaultMappingItemTransformer.class.getName());
-            put(Type.MAPPING_ITEM_TRANSFORMER, classNames);
+            classNames.add(PrefixItemTransformer.class.getName());
+            classNames.add(DefaultItemTransformer.class.getName());
+            put(Type.ITEM_TRANSFORMER, classNames);
 
             classNames = new HashSet<>();
             classNames.add(TestSampleJobDelegate.class.getName());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
new file mode 100644
index 0000000..80a386e
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.java.data.DefaultItemTransformer;
+
+public class PrefixItemTransformer extends DefaultItemTransformer {
+
+    public static final String PREFIX = "PREFIX_";
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item,
+            final Entity entity,
+            final List<PlainAttrValue> values) {
+
+        if (values == null || values.isEmpty() || values.get(0).getStringValue() == null) {
+            return super.beforePropagation(item, entity, values);
+        } else {
+            String value = values.get(0).getStringValue();
+            values.get(0).setStringValue(PREFIX + value);
+
+            return values;
+        }
+    }
+
+    @Override
+    public List<Object> beforePull(
+            final Item item,
+            final EntityTO entityTO,
+            final List<Object> values) {
+
+        if (values == null || values.isEmpty() || values.get(0) == null) {
+            return super.beforePull(item, entityTO, values);
+        } else {
+            List<Object> newValues = new ArrayList<>(values);
+            newValues.set(0, StringUtils.substringAfter(values.get(0).toString(), PREFIX));
+
+            return newValues;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
deleted file mode 100644
index 822860f..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core.reference;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.java.data.DefaultMappingItemTransformer;
-
-public class PrefixMappingItemTransformer extends DefaultMappingItemTransformer {
-
-    public static final String PREFIX = "PREFIX_";
-
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        if (values == null || values.isEmpty() || values.get(0).getStringValue() == null) {
-            return super.beforePropagation(mappingItem, any, values);
-        } else {
-            String value = values.get(0).getStringValue();
-            values.get(0).setStringValue(PREFIX + value);
-
-            return values;
-        }
-    }
-
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        if (values == null || values.isEmpty() || values.get(0) == null) {
-            return super.beforePull(mappingItem, anyTO, values);
-        } else {
-            List<Object> newValues = new ArrayList<>(values);
-            newValues.set(0, StringUtils.substringAfter(values.get(0).toString(), PREFIX));
-
-            return newValues;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
index c316741..72fa798 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
@@ -79,10 +79,10 @@ public class TestPullActions extends DefaultPullActions {
     }
 
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         AttrPatch fullnamePatch = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
index 1945320..a57980a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
@@ -144,7 +144,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         FormTester formTester = TESTER.newFormTester(
                 TAB_PANEL + "outerObjectsRepeater:2:outer:form:content:status:firstLevelContainer:"
@@ -181,7 +181,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.SUSPENDED, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         // re-activate
         TESTER.clickLink("body:realmsLI:realms");
@@ -236,7 +236,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:2:outer:dialog:footer:buttons:0:button",
                 Constants.ON_CLICK);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index 66df83e..2ccfd7e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -181,22 +181,16 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(component.getPageRelativePath() + ":actions:actionRepeater:0:action:action");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:0:value:oldAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:1:value:oldAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:textField", null);
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:textField", "even");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:textField", "even");
 
         TESTER.clickLink("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
                 + "secondLevelContainer:back");
@@ -232,22 +226,16 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(component.getPageRelativePath() + ":actions:actionRepeater:0:action:action");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:textField", "even");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:textField", "even");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:field-label", "ou");
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:0:value:newAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:1:value:newAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:textField", null);
 
         TESTER.clickLink("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
                 + "secondLevelContainer:back");

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
index 302441e..312b632 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
@@ -20,7 +20,6 @@ package org.apache.syncope.fit.console;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
@@ -113,41 +112,10 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(component.getPageRelativePath() + ":res", Constants.ON_CLICK);
         TESTER.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:provision");
 
-        // ------------------------------------------
-        // Check for realm provisioning feature availability (SYNCOPE-874)
-        // ------------------------------------------
-        FormTester formTester = TESTER.newFormTester("body:toggle:outerObjectsRepeater:3:outer:form");
-        formTester.setValue("content:aboutRealmProvison:enableRealmsProvision:checkboxField", true);
-
-        TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "enableRealmsProvision:checkboxField", Constants.ON_CHANGE);
-
-        assertNotNull(findComponentById(
-                "body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:realmsProvisionContainer",
-                "connObjectLink"));
-
-        TESTER.assertLabel("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "realmsProvisionContainer:connObjectLink:field-label", "Object Link");
-
-        formTester.setValue("content:aboutRealmProvison:enableRealmsProvision:checkboxField", false);
-
-        TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "enableRealmsProvision:checkboxField", Constants.ON_CHANGE);
-
-        try {
-            findComponentById(
-                    "body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:realmsProvisionContainer",
-                    "connObjectLink");
-            fail();
-        } catch (NullPointerException e) {
-            // correct
-        }
-        // ------------------------------------------
-
         TESTER.clickLink("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
                 + "content:group:beans:0:actions:actionRepeater:0:action:action");
 
-        formTester = TESTER.newFormTester(
+        FormTester formTester = TESTER.newFormTester(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:wizard:form");
         formTester.submit("buttons:next");
 
@@ -155,11 +123,11 @@ public class TopologyITCase extends AbstractConsoleITCase {
                 + "container:content:wizard:form:view:mapping:mappingContainer:mappings:1", WebMarkupContainer.class);
 
         TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
-                + "content:wizard:form:view:mapping:mappingContainer:mappings:1:mappingItemTransformers:icon",
+                + "content:wizard:form:view:mapping:mappingContainer:mappings:1:itemTransformers:icon",
                 Constants.ON_CLICK);
 
         TESTER.clickLink("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:"
-                + "wizard:form:view:mapping:mappingContainer:mappings:0:mappingItemTransformers:alertsLink");
+                + "wizard:form:view:mapping:mappingContainer:mappings:0:itemTransformers:alertsLink");
 
         TESTER.assertComponent("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
                 + "content:wizard:outerObjectsRepeater:0:outer:container:content:togglePanelContainer:"
@@ -203,7 +171,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         formTester = TESTER.newFormTester(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:wizard:form");
 
-        formTester.setValue("view:container:type:dropDownChoiceField", "0");
+        formTester.setValue("view:container:type:dropDownChoiceField", "1");
         formTester.setValue("view:container:clazz:textField", "__ACCOUNT__");
         formTester.submit("buttons:next");
         TESTER.assertNoErrorMessage();

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index 5bed533..02e744f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -52,7 +52,7 @@ import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -754,7 +754,7 @@ public class ConnectorITCase extends AbstractITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO mapItem = new MappingItemTO();
+            ItemTO mapItem = new ItemTO();
             mapItem.setExtAttrName("uid");
             mapItem.setIntAttrName("userId");
             mapItem.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
index 857e371..f325534 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
@@ -67,7 +67,7 @@ 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.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -948,13 +948,13 @@ public class GroupITCase extends AbstractITCase {
 
             MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
 
-            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
+            ItemTO connObjectKey = mapping.getConnObjectKeyItem();
             connObjectKey.setIntAttrName("displayProperty");
             connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
             mapping.setConnObjectKeyItem(connObjectKey);
             mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
 
-            MappingItemTO description = new MappingItemTO();
+            ItemTO description = new ItemTO();
             description.setIntAttrName("key");
             description.setExtAttrName("description");
             description.setPurpose(MappingPurpose.PROPAGATION);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
index 3c7f929..6a4abd1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -234,11 +234,11 @@ public class MembershipITCase extends AbstractITCase {
         ResourceTO newResource = resourceService.read(RESOURCE_NAME_DBPULL);
         newResource.setKey(getUUIDString());
 
-        MappingItemTO item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
-                new Predicate<MappingItemTO>() {
+        ItemTO item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
+                new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "firstname".equals(object.getIntAttrName());
             }
         });
@@ -248,10 +248,10 @@ public class MembershipITCase extends AbstractITCase {
         item.setPurpose(MappingPurpose.BOTH);
 
         item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
-                new Predicate<MappingItemTO>() {
+                new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "fullname".equals(object.getIntAttrName());
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
index 36286e0..7600340 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
@@ -38,7 +38,7 @@ import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
@@ -263,14 +263,14 @@ public class MigrationITCase extends AbstractTaskITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("username");
         item.setExtAttrName("username");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setPassword(true);
         item.setIntAttrName("password");
         item.setExtAttrName("__PASSWORD__");
@@ -278,56 +278,56 @@ public class MigrationITCase extends AbstractTaskITCase {
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_CIPHER_ALGORITHM);
         item.setExtAttrName("cipherAlgorithm");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("surname");
         item.setExtAttrName("surname");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("email");
         item.setExtAttrName("email");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("firstname");
         item.setExtAttrName("firstname");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("ctype");
         item.setExtAttrName("type");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("gender");
         item.setExtAttrName("gender");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("loginDate");
         item.setExtAttrName("loginDate");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_RESOURCES_SCHEMA);
         item.setExtAttrName("__RESOURCES__");
         item.setMandatoryCondition("false");
@@ -344,42 +344,42 @@ public class MigrationITCase extends AbstractTaskITCase {
         mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("name");
         item.setExtAttrName("name");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("show");
         item.setExtAttrName("show");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("title");
         item.setExtAttrName("title");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_RESOURCES_SCHEMA);
         item.setExtAttrName("__RESOURCES__");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_MEMBERSHIPS_SCHEMA);
         item.setExtAttrName("__MEMBERSHIPS__");
         item.setMandatoryCondition("false");

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
index 8c11fb7..b28e257 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
@@ -33,7 +33,7 @@ import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ProvisionTO;
@@ -151,13 +151,13 @@ public class MultitenancyITCase extends AbstractITCase {
             mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setIntAttrName("username");
             item.setExtAttrName("cn");
             item.setPurpose(MappingPurpose.BOTH);
             mapping.setConnObjectKeyItem(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setPassword(true);
             item.setIntAttrName("password");
             item.setExtAttrName("userPassword");
@@ -165,14 +165,14 @@ public class MultitenancyITCase extends AbstractITCase {
             item.setMandatoryCondition("true");
             mapping.add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("key");
             item.setPurpose(MappingPurpose.BOTH);
             item.setExtAttrName("sn");
             item.setMandatoryCondition("true");
             mapping.add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("email");
             item.setPurpose(MappingPurpose.BOTH);
             item.setExtAttrName("mail");

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
index 937c37b..f4aa9bf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -116,16 +116,16 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         ProvisionTO provision = resource.getProvision("PRINTER");
         assertNotNull(provision);
 
-        MappingItemTO mappingItem = IterableUtils.find(
-                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+        ItemTO mappingItem = IterableUtils.find(
+                provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "location".equals(object.getIntAttrName());
             }
         });
         assertNotNull(mappingItem);
-        assertTrue(mappingItem.getMappingItemTransformerClassNames().isEmpty());
+        assertTrue(mappingItem.getTransformerClassNames().isEmpty());
 
         String suffix = getUUIDString();
         mappingItem.setPropagationJEXLTransformer("value + '" + suffix + "'");

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index d1d85f8..c0ac469 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -61,7 +61,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
@@ -83,7 +83,7 @@ import org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions;
 import org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.fit.ActivitiDetector;
-import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
+import org.apache.syncope.fit.core.reference.PrefixItemTransformer;
 import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
 import org.apache.syncope.fit.core.reference.TestPullActions;
 import org.apache.syncope.fit.core.reference.TestPullRule;
@@ -417,17 +417,16 @@ public class PullTaskITCase extends AbstractTaskITCase {
         ProvisionTO provision = resource.getProvision("PRINTER");
         assertNotNull(provision);
 
-        MappingItemTO mappingItem = IterableUtils.find(
-                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+        ItemTO mappingItem = IterableUtils.find(provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "location".equals(object.getIntAttrName());
             }
         });
         assertNotNull(mappingItem);
-        mappingItem.getMappingItemTransformerClassNames().clear();
-        mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
+        mappingItem.getTransformerClassNames().clear();
+        mappingItem.getTransformerClassNames().add(PrefixItemTransformer.class.getName());
 
         try {
             resourceService.update(resource);
@@ -443,7 +442,7 @@ public class PullTaskITCase extends AbstractTaskITCase {
             // 1. create printer on external resource
             AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("pull");
             String originalLocation = anyObjectTO.getPlainAttr("location").getValues().get(0);
-            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
+            assertFalse(originalLocation.startsWith(PrefixItemTransformer.PREFIX));
 
             anyObjectTO = createAnyObject(anyObjectTO).getEntity();
             assertNotNull(anyObjectTO);
@@ -453,9 +452,9 @@ public class PullTaskITCase extends AbstractTaskITCase {
             ConnObjectTO connObjectTO = resourceService.
                     readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
             assertFalse(anyObjectTO.getPlainAttr("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
+                    startsWith(PrefixItemTransformer.PREFIX));
             assertTrue(connObjectTO.getAttr("LOCATION").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
+                    startsWith(PrefixItemTransformer.PREFIX));
 
             // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
             PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
index 4ed4a52..fe62261 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
@@ -346,7 +346,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setExtAttrName("cn");
             item.setIntAttrName(schemaTO.getKey());
             item.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
index aa096a6..bbe9ac5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
@@ -206,38 +206,54 @@ public class RealmITCase extends AbstractITCase {
         RealmTO childRealm = new RealmTO();
         childRealm.setName("child");
         childRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
+        RealmTO descendantRealm = new RealmTO();
+        descendantRealm.setName("test");
+        descendantRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
 
         // 2. check propagation
-        ProvisioningResult<RealmTO> result =
-                realmService.create("/", realm).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
-                });
-        ProvisioningResult<RealmTO> resultChild =
-                realmService.create("/test", childRealm).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
-                });
+        ProvisioningResult<RealmTO> result = realmService.create("/", realm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
         assertNotNull(result);
-        assertNotNull(resultChild);
         assertEquals(1, result.getPropagationStatuses().size());
-        assertEquals(1, resultChild.getPropagationStatuses().size());
         assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+        ProvisioningResult<RealmTO> resultChild = realmService.create("/test", childRealm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
+        assertNotNull(resultChild);
+        assertEquals(1, resultChild.getPropagationStatuses().size());
+        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUCCESS, resultChild.getPropagationStatuses().get(0).getStatus());
 
-        realm = result.getEntity();
+        ProvisioningResult<RealmTO> resultDescendant = realmService.create("/test/child", descendantRealm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
+        assertNotNull(resultDescendant);
+        assertEquals(1, resultDescendant.getPropagationStatuses().size());
+        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultDescendant.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, resultDescendant.getPropagationStatuses().get(0).getStatus());
 
         // 3. check on LDAP
-        assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
-
-        // 3.1. check on LDAP also child realm, it should be under test organizational unit
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,o=isp"));
-        assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
 
         // 4. remove realms
+        realmService.delete("/test/child/test");
         realmService.delete("/test/child");
-        realmService.delete(realm.getFullPath());
+        realmService.delete("/test");
 
         // 5. check on LDAP: both realms should be deleted
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index e91b393..bfa5d80 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -42,7 +42,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
@@ -78,19 +78,19 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setConnObjectKey(false);
@@ -134,20 +134,20 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("uid");
         item.setIntAttrName("userId");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setConnObjectKey(false);
@@ -193,7 +193,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
@@ -207,7 +207,7 @@ public class ResourceITCase extends AbstractITCase {
 
         mapping = new MappingTO();
         provisionTO.setMapping(mapping);
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("groupId");
         item.setConnObjectKey(true);
@@ -243,13 +243,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("email");
         // missing intAttrName ...
         mapping.add(item);
@@ -278,13 +278,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("usernane");
         // missing extAttrName ...
         mapping.add(item);
@@ -308,7 +308,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setConnObjectKey(true);
@@ -355,7 +355,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         // Update with an existing and already assigned mapping
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setKey("cc973ed6-d031-4790-adab-fc059ac0c818");
         item.setExtAttrName("test3");
         item.setIntAttrName("fullname");
@@ -364,13 +364,13 @@ public class ResourceITCase extends AbstractITCase {
 
         // Update defining new mappings
         for (int i = 4; i < 6; i++) {
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setExtAttrName("test" + i);
             item.setIntAttrName("fullname");
             item.setPurpose(MappingPurpose.BOTH);
             mapping.add(item);
         }
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setConnObjectKey(true);
@@ -382,7 +382,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(actual);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
+        Collection<ItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(4, mapItems.size());
     }
@@ -465,9 +465,15 @@ public class ResourceITCase extends AbstractITCase {
 
         OrgUnitTO orgUnit = new OrgUnitTO();
         orgUnit.setConnObjectLink("'ou=' + name + ',o=isp'");
-        orgUnit.setExtAttrName("ou");
         orgUnit.setObjectClass("organizationalUnit");
 
+        ItemTO item = new ItemTO();
+        item.setIntAttrName("name");
+        item.setExtAttrName("ou");
+        item.setMandatoryCondition("true");
+        item.setPurpose(MappingPurpose.BOTH);
+        orgUnit.setConnObjectKeyItem(item);
+
         resourceTO.setOrgUnit(orgUnit);
         resourceService.update(resourceTO);
         assertNull(resourceTO.getPropagationPriority());
@@ -684,13 +690,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("name");
         item.setExtAttrName("cn");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("userOwner");
         item.setExtAttrName("owner");
         item.setPurpose(MappingPurpose.BOTH);
@@ -729,14 +735,14 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(item);
 
-        MappingItemTO item2 = new MappingItemTO();
+        ItemTO item2 = new ItemTO();
         item2.setConnObjectKey(false);
         item2.setIntAttrName("gender");
         item2.setExtAttrName("gender");
@@ -751,7 +757,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
         assertEquals(MappingPurpose.PROPAGATION,
                 actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
-        for (MappingItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
+        for (ItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
             if ("gender".equals(itemTO.getIntAttrName())) {
                 assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
             }
@@ -773,7 +779,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provision.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setPurpose(MappingPurpose.BOTH);
@@ -803,7 +809,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
@@ -811,7 +817,7 @@ public class ResourceITCase extends AbstractITCase {
         mapping.setConnObjectKeyItem(item);
 
         // Add mapping for a not existing internal attribute
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("locatio");
         item.setExtAttrName("location");
         item.setPurpose(MappingPurpose.BOTH);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index 6e4cbca..948c426 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -38,7 +38,7 @@ import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.to.SAML2RequestTO;
 import org.apache.syncope.common.rest.api.service.SAML2SPService;
@@ -150,7 +150,7 @@ public class SAML2ITCase extends AbstractITCase {
 
         ssoCircle.getMappingItems().clear();
 
-        MappingItemTO keyMapping = new MappingItemTO();
+        ItemTO keyMapping = new ItemTO();
         keyMapping.setIntAttrName("email");
         keyMapping.setExtAttrName("EmailAddress");
         ssoCircle.setConnObjectKeyItem(keyMapping);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
index a1ddb44..ff0d094 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
@@ -50,7 +50,7 @@ import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
 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.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -611,7 +611,7 @@ public class UserIssuesITCase extends AbstractITCase {
     public void issueSYNCOPE354() {
         // change resource-ldap group mapping for including uniqueMember (need for assertions below)
         ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+        for (ItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("description".equals(item.getExtAttrName())) {
                 item.setExtAttrName("uniqueMember");
             }
@@ -658,7 +658,7 @@ public class UserIssuesITCase extends AbstractITCase {
                 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
 
         // 6. restore original resource-ldap group mapping
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+        for (ItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("uniqueMember".equals(item.getExtAttrName())) {
                 item.setExtAttrName("description");
             }
@@ -905,7 +905,7 @@ public class UserIssuesITCase extends AbstractITCase {
 
         MappingTO ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // change purpose from NONE to BOTH
-        for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
+        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
                 itemTO.setPurpose(MappingPurpose.BOTH);
             }
@@ -918,7 +918,7 @@ public class UserIssuesITCase extends AbstractITCase {
         assertNotNull(newWs1);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
+        Collection<ItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(7, mapItems.size());
 
@@ -943,7 +943,7 @@ public class UserIssuesITCase extends AbstractITCase {
         // 4.  restore resource ws-target-resource-1 mapping
         ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // restore purpose from BOTH to NONE
-        for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
+        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
                 itemTO.setPurpose(MappingPurpose.NONE);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
index 933cc99..5297257 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -273,10 +273,10 @@ public class VirAttrITCase extends AbstractITCase {
         try {
             // remove this mapping
             CollectionUtils.filterInverse(csv.getProvisions().get(0).getMapping().getItems(),
-                    new Predicate<MappingItemTO>() {
+                    new Predicate<ItemTO>() {
 
                 @Override
-                public boolean evaluate(final MappingItemTO item) {
+                public boolean evaluate(final ItemTO item) {
                     return "email".equals(item.getIntAttrName());
                 }
             });
@@ -504,20 +504,20 @@ public class VirAttrITCase extends AbstractITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setIntAttrName("fullname");
             item.setExtAttrName("ID");
             item.setPurpose(MappingPurpose.PROPAGATION);
             item.setConnObjectKey(true);
             mapping.setConnObjectKeyItem(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("username");
             item.setExtAttrName("USERNAME");
             item.setPurpose(MappingPurpose.PROPAGATION);
             mapping.getItems().add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("groups[" + groupName + "].rvirtualdata");
             item.setExtAttrName("EMAIL");
             item.setPurpose(MappingPurpose.PROPAGATION);
@@ -630,10 +630,10 @@ public class VirAttrITCase extends AbstractITCase {
         try {
             ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name());
             assertNotNull(provision);
-            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
                 @Override
-                public boolean evaluate(final MappingItemTO item) {
+                public boolean evaluate(final ItemTO item) {
                     return "mail".equals(item.getExtAttrName());
                 }
             });


[10/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
new file mode 100644
index 0000000..6975b2c
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import java.util.List;
+
+public interface ItemContainerTO {
+
+    void setConnObjectLink(String connObjectLink);
+
+    boolean setConnObjectKeyItem(ItemTO connObjectKeyItem);
+
+    boolean add(ItemTO item);
+
+    List<ItemTO> getItems();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
new file mode 100644
index 0000000..603b4d3
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+
+@XmlRootElement(name = "item")
+@XmlType
+public class ItemTO extends AbstractBaseBean implements EntityTO {
+
+    private static final long serialVersionUID = 2983498836767176862L;
+
+    private String key;
+
+    /**
+     * Attribute schema to be mapped. Consider that we can associate tha same attribute schema more than once, with
+     * different aliases, to different resource attributes.
+     */
+    private String intAttrName;
+
+    /**
+     * External resource's field to be mapped.
+     */
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is the key.
+     */
+    private boolean connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    private boolean password;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    private String mandatoryCondition = "false";
+
+    /**
+     * Mapping purposes.
+     */
+    private MappingPurpose purpose;
+
+    /**
+     * (Optional) JEXL expression to apply to values before propagation.
+     */
+    private String propagationJEXLTransformer;
+
+    /**
+     * (Optional) JEXL expression to apply to values before pull.
+     */
+    private String pullJEXLTransformer;
+
+    private final List<String> transformerClassNames = new ArrayList<>();
+
+    public boolean isConnObjectKey() {
+        return connObjectKey;
+    }
+
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = connObjectKey;
+    }
+
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @Override
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    public void setMandatoryCondition(final String mandatoryCondition) {
+        this.mandatoryCondition = mandatoryCondition;
+    }
+
+    public boolean isPassword() {
+        return password;
+    }
+
+    public void setPassword(final boolean password) {
+        this.password = password;
+    }
+
+    public String getIntAttrName() {
+        return intAttrName;
+    }
+
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+
+    public String getPropagationJEXLTransformer() {
+        return propagationJEXLTransformer;
+    }
+
+    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
+        this.propagationJEXLTransformer = propagationJEXLTransformer;
+    }
+
+    public String getPullJEXLTransformer() {
+        return pullJEXLTransformer;
+    }
+
+    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
+        this.pullJEXLTransformer = pullJEXLTransformer;
+    }
+
+    @XmlElementWrapper(name = "transformerClassNames")
+    @XmlElement(name = "transformerClassName")
+    @JsonProperty("transformerClassNames")
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
deleted file mode 100644
index c078950..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-
-@XmlRootElement(name = "mappingItem")
-@XmlType
-public class MappingItemTO extends AbstractBaseBean implements EntityTO {
-
-    private static final long serialVersionUID = 2983498836767176862L;
-
-    private String key;
-
-    /**
-     * Attribute schema to be mapped. Consider that we can associate tha same attribute schema more than once, with
-     * different aliases, to different resource attributes.
-     */
-    private String intAttrName;
-
-    /**
-     * External resource's field to be mapped.
-     */
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is the key.
-     */
-    private boolean connObjectKey;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    private boolean password;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    private String mandatoryCondition = "false";
-
-    /**
-     * Mapping purposes.
-     */
-    private MappingPurpose purpose;
-
-    /**
-     * (Optional) JEXL expression to apply to values before propagation.
-     */
-    private String propagationJEXLTransformer;
-
-    /**
-     * (Optional) JEXL expression to apply to values before pull.
-     */
-    private String pullJEXLTransformer;
-
-    private final List<String> mappingItemTransformerClassNames = new ArrayList<>();
-
-    public boolean isConnObjectKey() {
-        return connObjectKey;
-    }
-
-    public void setConnObjectKey(final boolean connObjectKey) {
-        this.connObjectKey = connObjectKey;
-    }
-
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
-    }
-
-    public boolean isPassword() {
-        return password;
-    }
-
-    public void setPassword(final boolean password) {
-        this.password = password;
-    }
-
-    public String getIntAttrName() {
-        return intAttrName;
-    }
-
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-
-    public String getPropagationJEXLTransformer() {
-        return propagationJEXLTransformer;
-    }
-
-    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
-        this.propagationJEXLTransformer = propagationJEXLTransformer;
-    }
-
-    public String getPullJEXLTransformer() {
-        return pullJEXLTransformer;
-    }
-
-    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
-        this.pullJEXLTransformer = pullJEXLTransformer;
-    }
-
-    @XmlElementWrapper(name = "mappingItemTransformerClassNames")
-    @XmlElement(name = "className")
-    @JsonProperty("mappingItemTransformerClassNames")
-    public List<String> getMappingItemTransformerClassNames() {
-        return mappingItemTransformerClassNames;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index a9048c7..8fe6224 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -31,42 +31,44 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "mapping")
 @XmlType
-public class MappingTO extends AbstractBaseBean {
+public class MappingTO extends AbstractBaseBean implements ItemContainerTO {
 
     private static final long serialVersionUID = 8447688036282611118L;
 
     private String connObjectLink;
 
-    private final List<MappingItemTO> items = new ArrayList<>();
+    private final List<ItemTO> items = new ArrayList<>();
 
-    private final List<MappingItemTO> linkingItems = new ArrayList<>();
+    private final List<ItemTO> linkingItems = new ArrayList<>();
 
     public String getConnObjectLink() {
         return connObjectLink;
     }
 
+    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
-        return IterableUtils.find(getItems(), new Predicate<MappingItemTO>() {
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });
     }
 
-    protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
         connObjectItem.setMandatoryCondition("true");
         connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);
     }
 
-    public boolean setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    @Override
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         return connObjectKeyItem == null
                 ? remove(getConnObjectKeyItem())
                 : addConnObjectKeyItem(connObjectKeyItem);
@@ -75,22 +77,24 @@ public class MappingTO extends AbstractBaseBean {
     @XmlElementWrapper(name = "items")
     @XmlElement(name = "item")
     @JsonProperty("items")
-    public List<MappingItemTO> getItems() {
+    @Override
+    public List<ItemTO> getItems() {
         return items;
     }
 
-    public boolean add(final MappingItemTO item) {
+    @Override
+    public boolean add(final ItemTO item) {
         return item == null ? false : this.items.contains(item) || this.items.add(item);
     }
 
-    public boolean remove(final MappingItemTO item) {
+    public boolean remove(final ItemTO item) {
         return this.items.remove(item);
     }
 
     @XmlElementWrapper(name = "linkingItems")
     @XmlElement(name = "item")
     @JsonProperty("linkingItems")
-    public List<MappingItemTO> getLinkingItems() {
+    public List<ItemTO> getLinkingItems() {
         return linkingItems;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
index 80743c0..1290c0c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
@@ -18,13 +18,20 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "orgUnit")
 @XmlType
-public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
+public class OrgUnitTO extends AbstractBaseBean implements EntityTO, ItemContainerTO {
 
     private static final long serialVersionUID = -1868877794174953177L;
 
@@ -34,10 +41,10 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
 
     private String syncToken;
 
-    private String extAttrName;
-
     private String connObjectLink;
 
+    private final List<ItemTO> items = new ArrayList<>();
+
     @Override
     public String getKey() {
         return key;
@@ -64,20 +71,53 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
         this.syncToken = syncToken;
     }
 
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
     public String getConnObjectLink() {
         return connObjectLink;
     }
 
+    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
+
+            @Override
+            public boolean evaluate(final ItemTO item) {
+                return item.isConnObjectKey();
+            }
+        });
+    }
+
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
+        connObjectItem.setMandatoryCondition("true");
+        connObjectItem.setConnObjectKey(true);
+
+        return this.add(connObjectItem);
+    }
+
+    @Override
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
+        return connObjectKeyItem == null
+                ? remove(getConnObjectKeyItem())
+                : addConnObjectKeyItem(connObjectKeyItem);
+    }
+
+    @XmlElementWrapper(name = "items")
+    @XmlElement(name = "item")
+    @JsonProperty("items")
+    @Override
+    public List<ItemTO> getItems() {
+        return items;
+    }
+
+    @Override
+    public boolean add(final ItemTO item) {
+        return item == null ? false : this.items.contains(item) || this.items.add(item);
+    }
+
+    public boolean remove(final ItemTO item) {
+        return this.items.remove(item);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/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 760b812..4593b77 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
@@ -179,19 +179,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
-        AnyType anyType = anyTypeDAO.find(anyTypeKey);
-        if (anyType == null) {
-            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
-        }
-        Provision provision = resource.getProvision(anyType);
-        if (provision == null) {
-            throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
-        }
-
-        Set<String> effectiveRealms = RealmUtils.getEffective(
-                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
-                resource.getConnector().getAdminRealm().getFullPath());
-        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
         Connector connector;
         try {
@@ -202,7 +189,30 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw sce;
         }
 
-        provision.setSyncToken(connector.getLatestSyncToken(provision.getObjectClass()));
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
+            if (resource.getOrgUnit() == null) {
+                throw new NotFoundException("Realm provision not enabled for Resource '" + key + "'");
+            }
+
+            resource.getOrgUnit().setSyncToken(connector.getLatestSyncToken(resource.getOrgUnit().getObjectClass()));
+        } else {
+            AnyType anyType = anyTypeDAO.find(anyTypeKey);
+            if (anyType == null) {
+                throw new NotFoundException("AnyType '" + anyTypeKey + "'");
+            }
+            Provision provision = resource.getProvision(anyType);
+            if (provision == null) {
+                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+            }
+
+            provision.setSyncToken(connector.getLatestSyncToken(provision.getObjectClass()));
+        }
+
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         resourceDAO.save(resource);
     }
 
@@ -212,13 +222,23 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
-        AnyType anyType = anyTypeDAO.find(anyTypeKey);
-        if (anyType == null) {
-            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
-        }
-        Provision provision = resource.getProvision(anyType);
-        if (provision == null) {
-            throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
+            if (resource.getOrgUnit() == null) {
+                throw new NotFoundException("Realm provision not enabled for Resource '" + key + "'");
+            }
+
+            resource.getOrgUnit().setSyncToken(null);
+        } else {
+            AnyType anyType = anyTypeDAO.find(anyTypeKey);
+            if (anyType == null) {
+                throw new NotFoundException("AnyType '" + anyTypeKey + "'");
+            }
+            Provision provision = resource.getProvision(anyType);
+            if (provision == null) {
+                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+            }
+
+            provision.setSyncToken(null);
         }
 
         Set<String> effectiveRealms = RealmUtils.getEffective(
@@ -226,7 +246,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 resource.getConnector().getAdminRealm().getFullPath());
         securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
-        provision.setSyncToken(null);
         resourceDAO.save(resource);
     }
 
@@ -364,7 +383,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             }
 
             objectClass = resource.getOrgUnit().getObjectClass();
-            options = MappingUtils.buildOperationOptions(resource.getOrgUnit());
+            options = MappingUtils.buildOperationOptions(
+                    MappingUtils.getPropagationItems(resource.getOrgUnit()).iterator());
         } else {
             Triple<ExternalResource, AnyType, Provision> init = connObjectInit(key, anyTypeKey);
             resource = init.getLeft();

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 2352813..c373311 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -220,8 +220,8 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
                 PLATFORM_INFO.getReportletConfs().addAll(implLookup.getClassNames(Type.REPORTLET_CONF));
                 PLATFORM_INFO.getAccountRules().addAll(implLookup.getClassNames(Type.ACCOUNT_RULE_CONF));
                 PLATFORM_INFO.getPasswordRules().addAll(implLookup.getClassNames(Type.PASSWORD_RULE_CONF));
-                PLATFORM_INFO.getMappingItemTransformers().addAll(
-                        implLookup.getClassNames(Type.MAPPING_ITEM_TRANSFORMER));
+                PLATFORM_INFO.getItemTransformers().addAll(
+                        implLookup.getClassNames(Type.ITEM_TRANSFORMER));
                 PLATFORM_INFO.getTaskJobs().addAll(implLookup.getClassNames(Type.TASKJOBDELEGATE));
                 PLATFORM_INFO.getReconciliationFilterBuilders().
                         addAll(implLookup.getClassNames(Type.RECONCILIATION_FILTER_BUILDER));

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index 8af1d44..2bc1eca 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -38,7 +38,7 @@ import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
 import org.apache.syncope.core.persistence.api.dao.Reportlet;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.core.provisioning.api.LogicActions;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
@@ -46,7 +46,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
 import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
 import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
-import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
+import org.apache.syncope.core.provisioning.java.data.JEXLItemTransformerImpl;
 import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate;
 import org.apache.syncope.core.provisioning.java.pushpull.PlainAttrsPullCorrelationRule;
 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
@@ -113,7 +113,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
         scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(AccountRule.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRule.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(MappingItemTransformer.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(ItemTransformer.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(ReconciliationFilterBuilder.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class));
@@ -166,10 +166,10 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                     }
                 }
 
-                if (MappingItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz
-                        && !clazz.equals(JEXLMappingItemTransformerImpl.class)) {
+                if (ItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz
+                        && !clazz.equals(JEXLItemTransformerImpl.class)) {
 
-                    classNames.get(Type.MAPPING_ITEM_TRANSFORMER).add(clazz.getName());
+                    classNames.get(Type.ITEM_TRANSFORMER).add(clazz.getName());
                 }
 
                 if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbstractClazz

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
index c510677..a81a2d6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
@@ -34,7 +34,7 @@ public interface ImplementationLookup extends SyncopeLoader {
         REPORTLET_CONF,
         ACCOUNT_RULE_CONF,
         PASSWORD_RULE_CONF,
-        MAPPING_ITEM_TRANSFORMER,
+        ITEM_TRANSFORMER,
         TASKJOBDELEGATE,
         RECONCILIATION_FILTER_BUILDER,
         LOGIC_ACTIONS,

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
index 5cefafb..de23601 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
@@ -34,6 +34,8 @@ public interface RealmDAO extends DAO<Realm> {
 
     Realm findByFullPath(String fullPath);
 
+    List<Realm> findByName(String name);
+
     List<Realm> findByResource(ExternalResource resource);
 
     <T extends Policy> List<Realm> findByPolicy(T policy);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
index 8b2cc2d..48ce512 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
@@ -133,7 +133,7 @@ public class LinkingMappingItem implements MappingItem {
     }
 
     @Override
-    public List<String> getMappingItemTransformerClassNames() {
+    public List<String> getTransformerClassNames() {
         return Collections.emptyList();
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
new file mode 100644
index 0000000..e8bf037
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.resource;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public interface Item extends Entity {
+
+    String getExtAttrName();
+
+    void setExtAttrName(String extAttrName);
+
+    String getIntAttrName();
+
+    void setIntAttrName(String intAttrName);
+
+    String getMandatoryCondition();
+
+    void setMandatoryCondition(String condition);
+
+    MappingPurpose getPurpose();
+
+    void setPurpose(MappingPurpose purpose);
+
+    boolean isConnObjectKey();
+
+    void setConnObjectKey(boolean connObjectKey);
+
+    boolean isPassword();
+
+    void setPassword(boolean password);
+
+    String getPropagationJEXLTransformer();
+
+    void setPropagationJEXLTransformer(String propagationJEXLTransformer);
+
+    String getPullJEXLTransformer();
+
+    void setPullJEXLTransformer(String pullJEXLTransformer);
+
+    List<String> getTransformerClassNames();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
index 5c14f18..92940a0 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
@@ -27,15 +27,15 @@ public interface Mapping extends Entity {
 
     void setProvision(Provision provision);
 
+    String getConnObjectLink();
+
+    void setConnObjectLink(String connObjectLink);
+
     boolean add(MappingItem item);
 
     MappingItem getConnObjectKeyItem();
 
     void setConnObjectKeyItem(MappingItem item);
 
-    String getConnObjectLink();
-
-    void setConnObjectLink(String connObjectLink);
-
     List<? extends MappingItem> getItems();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
index 461eaa1..24dc15d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
@@ -18,48 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.entity.resource;
 
-import java.util.List;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-
-public interface MappingItem extends Entity {
+public interface MappingItem extends Item {
 
     Mapping getMapping();
 
     void setMapping(Mapping mapping);
 
-    String getExtAttrName();
-
-    void setExtAttrName(String extAttrName);
-
-    String getIntAttrName();
-
-    void setIntAttrName(String intAttrName);
-
-    String getMandatoryCondition();
-
-    void setMandatoryCondition(String condition);
-
-    MappingPurpose getPurpose();
-
-    void setPurpose(MappingPurpose purpose);
-
-    boolean isConnObjectKey();
-
-    void setConnObjectKey(boolean connObjectKey);
-
-    boolean isPassword();
-
-    void setPassword(boolean password);
-
-    String getPropagationJEXLTransformer();
-
-    void setPropagationJEXLTransformer(String propagationJEXLTransformer);
-
-    String getPullJEXLTransformer();
-
-    void setPullJEXLTransformer(String pullJEXLTransformer);
-
-    List<String> getMappingItemTransformerClassNames();
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
index da8bee1..cdb0504 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity.resource;
 
+import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.SyncToken;
@@ -38,12 +39,15 @@ public interface OrgUnit extends Entity {
 
     void setSyncToken(SyncToken syncToken);
 
-    String getExtAttrName();
-
-    void setExtAttrName(String extAttrName);
-
     String getConnObjectLink();
 
     void setConnObjectLink(String connObjectLink);
 
+    boolean add(OrgUnitItem item);
+
+    OrgUnitItem getConnObjectKeyItem();
+
+    void setConnObjectKeyItem(OrgUnitItem item);
+
+    List<? extends OrgUnitItem> getItems();
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index 87cd26f..0f4cb62 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -63,6 +63,7 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
         return result;
     }
 
+    @Transactional(readOnly = true)
     @Override
     public Realm find(final String key) {
         return entityManager().find(JPARealm.class, key);
@@ -118,6 +119,15 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
     }
 
     @Override
+    public List<Realm> findByName(final String name) {
+        TypedQuery<Realm> query = entityManager().createQuery("SELECT e FROM " + JPARealm.class.getSimpleName() + " e "
+                + "WHERE e.name=:name", Realm.class);
+        query.setParameter("name", name);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<Realm> findByResource(final ExternalResource resource) {
         TypedQuery<Realm> query = entityManager().createQuery("SELECT e FROM " + JPARealm.class.getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources", Realm.class);
@@ -186,6 +196,7 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
         return result;
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<Realm> findAll() {
         return findDescendants(getRoot());

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 88f4e5a..66894e5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -127,7 +127,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnit;
 import org.apache.syncope.core.persistence.api.entity.DynRealm;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnitItem;
 
 @Component
 public class JPAEntityFactory implements EntityFactory {
@@ -219,6 +221,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPAMapping();
         } else if (reference.equals(MappingItem.class)) {
             result = (E) new JPAMappingItem();
+        } else if (reference.equals(OrgUnitItem.class)) {
+            result = (E) new JPAOrgUnitItem();
         } else if (reference.equals(GPlainAttr.class)) {
             result = (E) new JPAGPlainAttr();
         } else if (reference.equals(GPlainAttrValue.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
new file mode 100644
index 0000000..5bb91b9
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.resource;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.MappedSuperclass;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+
+@MappedSuperclass
+public abstract class AbstractItem extends AbstractGeneratedKeyEntity implements Item {
+
+    private static final long serialVersionUID = 5552380143129988272L;
+
+    @NotNull
+    private String intAttrName;
+
+    /**
+     * Target resource's field to be mapped.
+     */
+    @NotNull
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    @NotNull
+    private String mandatoryCondition;
+
+    /**
+     * Specify if the mapped target resource's field is the id.
+     */
+    @NotNull
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    @NotNull
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer password;
+
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    private MappingPurpose purpose;
+
+    /**
+     * (Optional) JEXL expression to apply to values before propagation.
+     */
+    @Column(name = "propJEXL")
+    private String propagationJEXLTransformer;
+
+    /**
+     * (Optional) JEXL expression to apply to values before pull.
+     */
+    @Column(name = "pullJEXL")
+    private String pullJEXLTransformer;
+
+    public AbstractItem() {
+        super();
+
+        mandatoryCondition = Boolean.FALSE.toString();
+
+        connObjectKey = getBooleanAsInteger(false);
+        password = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    @Override
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    @Override
+    public void setMandatoryCondition(final String mandatoryCondition) {
+        this.mandatoryCondition = mandatoryCondition;
+    }
+
+    @Override
+    public String getIntAttrName() {
+        return intAttrName;
+    }
+
+    @Override
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    @Override
+    public boolean isConnObjectKey() {
+        return isBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = getBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public boolean isPassword() {
+        return isBooleanAsInteger(password);
+    }
+
+    @Override
+    public void setPassword(final boolean password) {
+        this.password = getBooleanAsInteger(password);
+    }
+
+    @Override
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    @Override
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+
+    @Override
+    public String getPropagationJEXLTransformer() {
+        return propagationJEXLTransformer;
+    }
+
+    @Override
+    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
+        this.propagationJEXLTransformer = propagationJEXLTransformer;
+    }
+
+    @Override
+    public String getPullJEXLTransformer() {
+        return pullJEXLTransformer;
+    }
+
+    @Override
+    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
+        this.pullJEXLTransformer = pullJEXLTransformer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
index 3894994..bac3955 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -27,7 +27,6 @@ import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
@@ -44,8 +43,7 @@ public class JPAMapping extends AbstractGeneratedKeyEntity implements Mapping {
 
     public static final String TABLE = "Mapping";
 
-    @NotNull
-    @OneToOne
+    @OneToOne(optional = false)
     private JPAProvision provision;
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
index 47dac59..8624a70 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -20,30 +20,22 @@ package org.apache.syncope.core.persistence.jpa.entity.resource;
 
 import java.util.ArrayList;
 import java.util.List;
-import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import javax.validation.constraints.NotNull;
-import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
 
 @Entity
 @Table(name = JPAMappingItem.TABLE)
 @Cacheable
-public class JPAMappingItem extends AbstractGeneratedKeyEntity implements MappingItem {
+public class JPAMappingItem extends AbstractItem implements MappingItem {
 
     private static final long serialVersionUID = 7383601853619332424L;
 
@@ -52,73 +44,15 @@ public class JPAMappingItem extends AbstractGeneratedKeyEntity implements Mappin
     @ManyToOne
     private JPAMapping mapping;
 
-    @NotNull
-    private String intAttrName;
-
-    /**
-     * Target resource's field to be mapped.
-     */
-    @NotNull
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    @NotNull
-    private String mandatoryCondition;
-
-    /**
-     * Specify if the mapped target resource's field is the id.
-     */
-    @NotNull
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer connObjectKey;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    @NotNull
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer password;
-
-    @NotNull
-    @Enumerated(EnumType.STRING)
-    private MappingPurpose purpose;
-
-    /**
-     * (Optional) JEXL expression to apply to values before propagation.
-     */
-    @Column(name = "propJEXL")
-    private String propagationJEXLTransformer;
-
-    /**
-     * (Optional) JEXL expression to apply to values before pull.
-     */
-    @Column(name = "pullJEXL")
-    private String pullJEXLTransformer;
-
     /**
      * (Optional) classes for MappingItem transformation.
      */
     @ElementCollection(fetch = FetchType.EAGER)
     @Column(name = "transformerClassName")
-    @CollectionTable(name = "MappingItem_Transformer",
+    @CollectionTable(name = TABLE + "_Transformer",
             joinColumns =
             @JoinColumn(name = "mappingItem_id", referencedColumnName = "id"))
-    private List<String> mappingItemTransformerClassNames = new ArrayList<>();
-
-    public JPAMappingItem() {
-        super();
-
-        mandatoryCondition = Boolean.FALSE.toString();
-
-        connObjectKey = getBooleanAsInteger(false);
-        password = getBooleanAsInteger(false);
-    }
+    private List<String> transformerClassNames = new ArrayList<>();
 
     @Override
     public Mapping getMapping() {
@@ -132,88 +66,7 @@ public class JPAMappingItem extends AbstractGeneratedKeyEntity implements Mappin
     }
 
     @Override
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
     }
-
-    @Override
-    public String getIntAttrName() {
-        return intAttrName;
-    }
-
-    @Override
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    @Override
-    public boolean isConnObjectKey() {
-        return isBooleanAsInteger(connObjectKey);
-    }
-
-    @Override
-    public void setConnObjectKey(final boolean connObjectKey) {
-        this.connObjectKey = getBooleanAsInteger(connObjectKey);
-    }
-
-    @Override
-    public boolean isPassword() {
-        return isBooleanAsInteger(password);
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        this.password = getBooleanAsInteger(password);
-    }
-
-    @Override
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-
-    @Override
-    public String getPropagationJEXLTransformer() {
-        return propagationJEXLTransformer;
-    }
-
-    @Override
-    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
-        this.propagationJEXLTransformer = propagationJEXLTransformer;
-    }
-
-    @Override
-    public String getPullJEXLTransformer() {
-        return pullJEXLTransformer;
-    }
-
-    @Override
-    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
-        this.pullJEXLTransformer = pullJEXLTransformer;
-    }
-
-    @Override
-    public List<String> getMappingItemTransformerClassNames() {
-        return mappingItemTransformerClassNames;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
index 7324bfc..ab4398d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
@@ -18,13 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.resource;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Lob;
+import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@@ -50,11 +58,11 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit {
     private String serializedSyncToken;
 
     @NotNull
-    private String extAttrName;
-
-    @NotNull
     private String connObjectLink;
 
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "orgUnit")
+    private List<JPAOrgUnitItem> items = new ArrayList<>();
+
     @Override
     public ExternalResource getResource() {
         return resource;
@@ -96,23 +104,40 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit {
     }
 
     @Override
-    public String getExtAttrName() {
-        return extAttrName;
+    public String getConnObjectLink() {
+        return connObjectLink;
     }
 
     @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
+    public void setConnObjectLink(final String connObjectLink) {
+        this.connObjectLink = connObjectLink;
     }
 
     @Override
-    public String getConnObjectLink() {
-        return connObjectLink;
+    public boolean add(final OrgUnitItem item) {
+        checkType(item, JPAOrgUnitItem.class);
+        return items.contains((JPAOrgUnitItem) item) || items.add((JPAOrgUnitItem) item);
     }
 
     @Override
-    public void setConnObjectLink(final String connObjectLink) {
-        this.connObjectLink = connObjectLink;
+    public List<? extends OrgUnitItem> getItems() {
+        return items;
+    }
+
+    @Override
+    public OrgUnitItem getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.isConnObjectKey();
+            }
+        });
     }
 
+    @Override
+    public void setConnObjectKeyItem(final OrgUnitItem item) {
+        item.setConnObjectKey(true);
+        this.add(item);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
new file mode 100644
index 0000000..e356ff2
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
+
+@Entity
+@Table(name = JPAOrgUnitItem.TABLE)
+@Cacheable
+public class JPAOrgUnitItem extends AbstractItem implements OrgUnitItem {
+
+    private static final long serialVersionUID = 7872073846646341777L;
+
+    public static final String TABLE = "OrgUnitItem";
+
+    @ManyToOne
+    private JPAOrgUnit orgUnit;
+
+    /**
+     * (Optional) classes for MappingItem transformation.
+     */
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "transformerClassName")
+    @CollectionTable(name = TABLE + "_Transformer",
+            joinColumns =
+            @JoinColumn(name = "orgUnitItem_id", referencedColumnName = "id"))
+    private List<String> transformerClassNames = new ArrayList<>();
+
+    @Override
+    public OrgUnit getOrgUnit() {
+        return orgUnit;
+    }
+
+    @Override
+    public void setOrgUnit(final OrgUnit mapping) {
+        checkType(mapping, JPAOrgUnit.class);
+        this.orgUnit = (JPAOrgUnit) mapping;
+    }
+
+    @Override
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 80f4d6e..719a240 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.collections4.IterableUtils;
@@ -26,24 +27,22 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class ExternalResourceValidator extends AbstractValidator<ExternalResourceCheck, ExternalResource> {
 
-    private boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
-        if (mapping == null) {
-            return true;
-        }
-
-        long connObjectKeys = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
+    private boolean isValid(final List<? extends Item> items, final ConstraintValidatorContext context) {
+        long connObjectKeys = IterableUtils.countMatches(items, new Predicate<Item>() {
 
             @Override
-            public boolean evaluate(final MappingItem item) {
+            public boolean evaluate(final Item item) {
                 return item.isConnObjectKey();
             }
         });
@@ -56,36 +55,22 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
 
         boolean isValid = true;
 
-        long passwords = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
-
-            @Override
-            public boolean evaluate(final MappingItem item) {
-                return item.isPassword();
-            }
-        });
-        if (passwords > 1) {
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
-                    addPropertyNode("password.size").addConstraintViolation();
-            isValid = false;
-        }
-
-        for (MappingItem item : mapping.getItems()) {
-            for (String className : item.getMappingItemTransformerClassNames()) {
+        for (Item item : items) {
+            for (String className : item.getTransformerClassNames()) {
                 Class<?> actionsClass = null;
                 boolean isAssignable = false;
                 try {
                     actionsClass = Class.forName(className);
-                    isAssignable = MappingItemTransformer.class.isAssignableFrom(actionsClass);
+                    isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass);
                 } catch (Exception e) {
-                    LOG.error("Invalid MappingItemTransformer specified: {}", className, e);
+                    LOG.error("Invalid ItemTransformer specified: {}", className, e);
                 }
 
                 if (actionsClass == null || !isAssignable) {
                     context.buildConstraintViolationWithTemplate(
                             getTemplate(EntityViolationType.InvalidMapping,
-                                    "Invalid mapping item trasformer class name")).
-                            addPropertyNode("mappingItemTransformerClassName").addConstraintViolation();
+                                    "Invalid item trasformer class name")).
+                            addPropertyNode("itemTransformerClassName").addConstraintViolation();
                     isValid = false;
                 }
             }
@@ -94,6 +79,38 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
         return isValid;
     }
 
+    private boolean isValid(final OrgUnit orgUnit, final ConstraintValidatorContext context) {
+        if (orgUnit == null) {
+            return true;
+        }
+
+        return isValid(orgUnit.getItems(), context);
+    }
+
+    private boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
+        if (mapping == null) {
+            return true;
+        }
+
+        boolean isValid = true;
+
+        long passwords = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.isPassword();
+            }
+        });
+        if (passwords > 1) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
+                    addPropertyNode("password.size").addConstraintViolation();
+            isValid = false;
+        }
+
+        return isValid && isValid(mapping.getItems(), context);
+    }
+
     @Override
     public boolean isValid(final ExternalResource resource, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
@@ -138,6 +155,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
                 return isValid(provision.getMapping(), context);
             }
         });
+        validMappings &= isValid(resource.getOrgUnit(), context);
 
         if (anyTypes.size() < resource.getProvisions().size()) {
             context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index b88aee1..0e1598e 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -799,10 +799,16 @@ under the License.
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["entryUUID"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":true,"order":7,"confidential":false,"defaultValues":[]},"overridable":true,"values":["o=isp"]}]'/>
+                    jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":true,"order":7,"confidential":false,"defaultValues":[]},"overridable":true,"values":["o=isp"]}]'/>
   <OrgUnit id="599a59cf-9a23-4447-9a59-cf9a2334473a" connObjectLink="syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'"
-           extAttrName="ou" objectClass="organizationalUnit" resource_id="resource-ldap-orgunit"/>
-
+           objectClass="organizationalUnit" resource_id="resource-ldap-orgunit"/>
+  <OrgUnitItem id="5d0e7ad0-9026-42ad-be8a-32539389e7bd" connObjectKey="1" extAttrName="l"
+               intAttrName="fullpath" mandatoryCondition="true" purpose="BOTH"
+               orgUnit_id="599a59cf-9a23-4447-9a59-cf9a2334473a"/>
+  <OrgUnitItem id="1df556d3-bc23-48b7-a09b-fc3794a00019" connObjectKey="0" extAttrName="ou"
+               intAttrName="name" mandatoryCondition="true" purpose="BOTH"
+               orgUnit_id="599a59cf-9a23-4447-9a59-cf9a2334473a"/>
+  
   <ExternalResource id="ws-target-resource-nopropagation" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
index 8d0be03..daa09e2 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
@@ -22,10 +22,14 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 
@@ -41,6 +45,15 @@ public interface MappingManager {
     String getConnObjectKeyValue(Any<?> any, Provision provision);
 
     /**
+     * Get connObjectKey internal value.
+     *
+     * @param realm realm
+     * @param orgUnit orgUnit information
+     * @return connObjectKey internal value
+     */
+    String getConnObjectKeyValue(Realm realm, OrgUnit orgUnit);
+
+    /**
      * Get attribute values for the given {@link MappingItem} and any object.
      *
      * @param provision provision information
@@ -65,6 +78,15 @@ public interface MappingManager {
             Any<?> any, String password, boolean changePwd, Boolean enable, Provision provision);
 
     /**
+     * Prepare attributes for sending to a connector instance.
+     *
+     * @param realm Realm
+     * @param orgUnit provision information
+     * @return connObjectLink + prepared attributes
+     */
+    Pair<String, Set<Attribute>> prepareAttrs(Realm realm, OrgUnit orgUnit);
+
+    /**
      * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
      * connector.
      *
@@ -76,4 +98,14 @@ public interface MappingManager {
      */
     <T extends AnyTO> void setIntValues(MappingItem mapItem, Attribute attr, T anyTO, AnyUtils anyUtils);
 
+    /**
+     * Set attribute values, according to the given {@link OrgUnitItem}, to realm from attribute received from
+     * connector.
+     *
+     * @param orgUnitItem mapping item
+     * @param attr attribute received from connector
+     * @param realmTO realm
+     */
+    void setIntValues(OrgUnitItem orgUnitItem, Attribute attr, RealmTO realmTO);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
new file mode 100644
index 0000000..1ec16c3
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+
+/**
+ * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter)
+ * the Syncope internal storage.
+ *
+ * These transformations are not applied to virtual attribute values.
+ */
+public interface ItemTransformer {
+
+    /**
+     * Invoked while preparing attribute values to be sent out to external resource during propagation.
+     *
+     * @param item mapping item
+     * @param entity entity
+     * @param values original values
+     * @return transformed values
+     */
+    List<PlainAttrValue> beforePropagation(
+            Item item,
+            Entity entity,
+            List<PlainAttrValue> values);
+
+    /**
+     * Invoked while reading attribute values from external resource during pull.
+     *
+     * @param item mapping item
+     * @param entityTO entity
+     * @param values original values
+     * @return transformed values
+     */
+    List<Object> beforePull(
+            Item item,
+            EntityTO entityTO,
+            List<Object> values);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
new file mode 100644
index 0000000..3194454
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+/**
+ * {@link ItemTransformer} implementing evaluation of JEXL expression defined for a given
+ * {@link org.apache.syncope.core.persistence.api.entity.resource.MappingItem}.
+ */
+public interface JEXLItemTransformer extends ItemTransformer {
+
+    void setPropagationJEXL(String propagationJEXL);
+
+    void setPullJEXL(String pullJEXL);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
deleted file mode 100644
index 8717e3d..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.data;
-
-/**
- * {@link MappingItemTransformer} implementing evaluation of JEXL expression defined for a given
- * {@link org.apache.syncope.core.persistence.api.entity.resource.MappingItem}.
- */
-public interface JEXLMappingItemTransformer extends MappingItemTransformer {
-
-    void setPropagationJEXL(String propagationJEXL);
-
-    void setPullJEXL(String pullJEXL);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
deleted file mode 100644
index d8cb012..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.data;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-
-/**
- * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter)
- * the Syncope internal storage.
- *
- * These transformations are not applied to virtual attribute values.
- */
-public interface MappingItemTransformer {
-
-    /**
-     * Invoked while preparing attribute values to be sent out to external resource during propagation.
-     *
-     * @param mappingItem mapping item
-     * @param any any object
-     * @param values original values
-     * @return transformed values
-     */
-    List<PlainAttrValue> beforePropagation(
-            MappingItem mappingItem,
-            Any<?> any,
-            List<PlainAttrValue> values);
-
-    /**
-     * Invoked while reading attribute values from external resource during pull.
-     *
-     * @param mappingItem mapping item
-     * @param anyTO any object
-     * @param values original values
-     * @return transformed values
-     */
-    List<Object> beforePull(
-            MappingItem mappingItem,
-            AnyTO anyTO,
-            List<Object> values);
-}


[04/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
new file mode 100644
index 0000000..6975b2c
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import java.util.List;
+
+public interface ItemContainerTO {
+
+    void setConnObjectLink(String connObjectLink);
+
+    boolean setConnObjectKeyItem(ItemTO connObjectKeyItem);
+
+    boolean add(ItemTO item);
+
+    List<ItemTO> getItems();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
new file mode 100644
index 0000000..603b4d3
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+
+@XmlRootElement(name = "item")
+@XmlType
+public class ItemTO extends AbstractBaseBean implements EntityTO {
+
+    private static final long serialVersionUID = 2983498836767176862L;
+
+    private String key;
+
+    /**
+     * Attribute schema to be mapped. Consider that we can associate tha same attribute schema more than once, with
+     * different aliases, to different resource attributes.
+     */
+    private String intAttrName;
+
+    /**
+     * External resource's field to be mapped.
+     */
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is the key.
+     */
+    private boolean connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    private boolean password;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    private String mandatoryCondition = "false";
+
+    /**
+     * Mapping purposes.
+     */
+    private MappingPurpose purpose;
+
+    /**
+     * (Optional) JEXL expression to apply to values before propagation.
+     */
+    private String propagationJEXLTransformer;
+
+    /**
+     * (Optional) JEXL expression to apply to values before pull.
+     */
+    private String pullJEXLTransformer;
+
+    private final List<String> transformerClassNames = new ArrayList<>();
+
+    public boolean isConnObjectKey() {
+        return connObjectKey;
+    }
+
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = connObjectKey;
+    }
+
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @Override
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    public void setMandatoryCondition(final String mandatoryCondition) {
+        this.mandatoryCondition = mandatoryCondition;
+    }
+
+    public boolean isPassword() {
+        return password;
+    }
+
+    public void setPassword(final boolean password) {
+        this.password = password;
+    }
+
+    public String getIntAttrName() {
+        return intAttrName;
+    }
+
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+
+    public String getPropagationJEXLTransformer() {
+        return propagationJEXLTransformer;
+    }
+
+    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
+        this.propagationJEXLTransformer = propagationJEXLTransformer;
+    }
+
+    public String getPullJEXLTransformer() {
+        return pullJEXLTransformer;
+    }
+
+    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
+        this.pullJEXLTransformer = pullJEXLTransformer;
+    }
+
+    @XmlElementWrapper(name = "transformerClassNames")
+    @XmlElement(name = "transformerClassName")
+    @JsonProperty("transformerClassNames")
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
deleted file mode 100644
index c078950..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-
-@XmlRootElement(name = "mappingItem")
-@XmlType
-public class MappingItemTO extends AbstractBaseBean implements EntityTO {
-
-    private static final long serialVersionUID = 2983498836767176862L;
-
-    private String key;
-
-    /**
-     * Attribute schema to be mapped. Consider that we can associate tha same attribute schema more than once, with
-     * different aliases, to different resource attributes.
-     */
-    private String intAttrName;
-
-    /**
-     * External resource's field to be mapped.
-     */
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is the key.
-     */
-    private boolean connObjectKey;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    private boolean password;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    private String mandatoryCondition = "false";
-
-    /**
-     * Mapping purposes.
-     */
-    private MappingPurpose purpose;
-
-    /**
-     * (Optional) JEXL expression to apply to values before propagation.
-     */
-    private String propagationJEXLTransformer;
-
-    /**
-     * (Optional) JEXL expression to apply to values before pull.
-     */
-    private String pullJEXLTransformer;
-
-    private final List<String> mappingItemTransformerClassNames = new ArrayList<>();
-
-    public boolean isConnObjectKey() {
-        return connObjectKey;
-    }
-
-    public void setConnObjectKey(final boolean connObjectKey) {
-        this.connObjectKey = connObjectKey;
-    }
-
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
-    }
-
-    public boolean isPassword() {
-        return password;
-    }
-
-    public void setPassword(final boolean password) {
-        this.password = password;
-    }
-
-    public String getIntAttrName() {
-        return intAttrName;
-    }
-
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-
-    public String getPropagationJEXLTransformer() {
-        return propagationJEXLTransformer;
-    }
-
-    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
-        this.propagationJEXLTransformer = propagationJEXLTransformer;
-    }
-
-    public String getPullJEXLTransformer() {
-        return pullJEXLTransformer;
-    }
-
-    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
-        this.pullJEXLTransformer = pullJEXLTransformer;
-    }
-
-    @XmlElementWrapper(name = "mappingItemTransformerClassNames")
-    @XmlElement(name = "className")
-    @JsonProperty("mappingItemTransformerClassNames")
-    public List<String> getMappingItemTransformerClassNames() {
-        return mappingItemTransformerClassNames;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index a9048c7..8fe6224 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -31,42 +31,44 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "mapping")
 @XmlType
-public class MappingTO extends AbstractBaseBean {
+public class MappingTO extends AbstractBaseBean implements ItemContainerTO {
 
     private static final long serialVersionUID = 8447688036282611118L;
 
     private String connObjectLink;
 
-    private final List<MappingItemTO> items = new ArrayList<>();
+    private final List<ItemTO> items = new ArrayList<>();
 
-    private final List<MappingItemTO> linkingItems = new ArrayList<>();
+    private final List<ItemTO> linkingItems = new ArrayList<>();
 
     public String getConnObjectLink() {
         return connObjectLink;
     }
 
+    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
-        return IterableUtils.find(getItems(), new Predicate<MappingItemTO>() {
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });
     }
 
-    protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
         connObjectItem.setMandatoryCondition("true");
         connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);
     }
 
-    public boolean setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    @Override
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         return connObjectKeyItem == null
                 ? remove(getConnObjectKeyItem())
                 : addConnObjectKeyItem(connObjectKeyItem);
@@ -75,22 +77,24 @@ public class MappingTO extends AbstractBaseBean {
     @XmlElementWrapper(name = "items")
     @XmlElement(name = "item")
     @JsonProperty("items")
-    public List<MappingItemTO> getItems() {
+    @Override
+    public List<ItemTO> getItems() {
         return items;
     }
 
-    public boolean add(final MappingItemTO item) {
+    @Override
+    public boolean add(final ItemTO item) {
         return item == null ? false : this.items.contains(item) || this.items.add(item);
     }
 
-    public boolean remove(final MappingItemTO item) {
+    public boolean remove(final ItemTO item) {
         return this.items.remove(item);
     }
 
     @XmlElementWrapper(name = "linkingItems")
     @XmlElement(name = "item")
     @JsonProperty("linkingItems")
-    public List<MappingItemTO> getLinkingItems() {
+    public List<ItemTO> getLinkingItems() {
         return linkingItems;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
index 80743c0..1290c0c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
@@ -18,13 +18,20 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "orgUnit")
 @XmlType
-public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
+public class OrgUnitTO extends AbstractBaseBean implements EntityTO, ItemContainerTO {
 
     private static final long serialVersionUID = -1868877794174953177L;
 
@@ -34,10 +41,10 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
 
     private String syncToken;
 
-    private String extAttrName;
-
     private String connObjectLink;
 
+    private final List<ItemTO> items = new ArrayList<>();
+
     @Override
     public String getKey() {
         return key;
@@ -64,20 +71,53 @@ public class OrgUnitTO extends AbstractBaseBean implements EntityTO {
         this.syncToken = syncToken;
     }
 
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
     public String getConnObjectLink() {
         return connObjectLink;
     }
 
+    @Override
     public void setConnObjectLink(final String connObjectLink) {
         this.connObjectLink = connObjectLink;
     }
 
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
+
+            @Override
+            public boolean evaluate(final ItemTO item) {
+                return item.isConnObjectKey();
+            }
+        });
+    }
+
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
+        connObjectItem.setMandatoryCondition("true");
+        connObjectItem.setConnObjectKey(true);
+
+        return this.add(connObjectItem);
+    }
+
+    @Override
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
+        return connObjectKeyItem == null
+                ? remove(getConnObjectKeyItem())
+                : addConnObjectKeyItem(connObjectKeyItem);
+    }
+
+    @XmlElementWrapper(name = "items")
+    @XmlElement(name = "item")
+    @JsonProperty("items")
+    @Override
+    public List<ItemTO> getItems() {
+        return items;
+    }
+
+    @Override
+    public boolean add(final ItemTO item) {
+        return item == null ? false : this.items.contains(item) || this.items.add(item);
+    }
+
+    public boolean remove(final ItemTO item) {
+        return this.items.remove(item);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/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 760b812..4593b77 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
@@ -179,19 +179,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
-        AnyType anyType = anyTypeDAO.find(anyTypeKey);
-        if (anyType == null) {
-            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
-        }
-        Provision provision = resource.getProvision(anyType);
-        if (provision == null) {
-            throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
-        }
-
-        Set<String> effectiveRealms = RealmUtils.getEffective(
-                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
-                resource.getConnector().getAdminRealm().getFullPath());
-        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
         Connector connector;
         try {
@@ -202,7 +189,30 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw sce;
         }
 
-        provision.setSyncToken(connector.getLatestSyncToken(provision.getObjectClass()));
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
+            if (resource.getOrgUnit() == null) {
+                throw new NotFoundException("Realm provision not enabled for Resource '" + key + "'");
+            }
+
+            resource.getOrgUnit().setSyncToken(connector.getLatestSyncToken(resource.getOrgUnit().getObjectClass()));
+        } else {
+            AnyType anyType = anyTypeDAO.find(anyTypeKey);
+            if (anyType == null) {
+                throw new NotFoundException("AnyType '" + anyTypeKey + "'");
+            }
+            Provision provision = resource.getProvision(anyType);
+            if (provision == null) {
+                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+            }
+
+            provision.setSyncToken(connector.getLatestSyncToken(provision.getObjectClass()));
+        }
+
+        Set<String> effectiveRealms = RealmUtils.getEffective(
+                AuthContextUtils.getAuthorizations().get(StandardEntitlement.RESOURCE_UPDATE),
+                resource.getConnector().getAdminRealm().getFullPath());
+        securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
+
         resourceDAO.save(resource);
     }
 
@@ -212,13 +222,23 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + key + "'");
         }
-        AnyType anyType = anyTypeDAO.find(anyTypeKey);
-        if (anyType == null) {
-            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
-        }
-        Provision provision = resource.getProvision(anyType);
-        if (provision == null) {
-            throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyTypeKey)) {
+            if (resource.getOrgUnit() == null) {
+                throw new NotFoundException("Realm provision not enabled for Resource '" + key + "'");
+            }
+
+            resource.getOrgUnit().setSyncToken(null);
+        } else {
+            AnyType anyType = anyTypeDAO.find(anyTypeKey);
+            if (anyType == null) {
+                throw new NotFoundException("AnyType '" + anyTypeKey + "'");
+            }
+            Provision provision = resource.getProvision(anyType);
+            if (provision == null) {
+                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + "'");
+            }
+
+            provision.setSyncToken(null);
         }
 
         Set<String> effectiveRealms = RealmUtils.getEffective(
@@ -226,7 +246,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 resource.getConnector().getAdminRealm().getFullPath());
         securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
-        provision.setSyncToken(null);
         resourceDAO.save(resource);
     }
 
@@ -364,7 +383,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             }
 
             objectClass = resource.getOrgUnit().getObjectClass();
-            options = MappingUtils.buildOperationOptions(resource.getOrgUnit());
+            options = MappingUtils.buildOperationOptions(
+                    MappingUtils.getPropagationItems(resource.getOrgUnit()).iterator());
         } else {
             Triple<ExternalResource, AnyType, Provision> init = connObjectInit(key, anyTypeKey);
             resource = init.getLeft();

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index c562de9..03635bb 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -223,8 +223,8 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
                 PLATFORM_INFO.getReportletConfs().addAll(implLookup.getClassNames(Type.REPORTLET_CONF));
                 PLATFORM_INFO.getAccountRules().addAll(implLookup.getClassNames(Type.ACCOUNT_RULE_CONF));
                 PLATFORM_INFO.getPasswordRules().addAll(implLookup.getClassNames(Type.PASSWORD_RULE_CONF));
-                PLATFORM_INFO.getMappingItemTransformers().addAll(
-                        implLookup.getClassNames(Type.MAPPING_ITEM_TRANSFORMER));
+                PLATFORM_INFO.getItemTransformers().addAll(
+                        implLookup.getClassNames(Type.ITEM_TRANSFORMER));
                 PLATFORM_INFO.getTaskJobs().addAll(implLookup.getClassNames(Type.TASKJOBDELEGATE));
                 PLATFORM_INFO.getReconciliationFilterBuilders().
                         addAll(implLookup.getClassNames(Type.RECONCILIATION_FILTER_BUILDER));

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index 8af1d44..2bc1eca 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -38,7 +38,7 @@ import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
 import org.apache.syncope.core.persistence.api.dao.Reportlet;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.core.provisioning.api.LogicActions;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
@@ -46,7 +46,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
 import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
 import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
-import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
+import org.apache.syncope.core.provisioning.java.data.JEXLItemTransformerImpl;
 import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate;
 import org.apache.syncope.core.provisioning.java.pushpull.PlainAttrsPullCorrelationRule;
 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
@@ -113,7 +113,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
         scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(AccountRule.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRule.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(MappingItemTransformer.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(ItemTransformer.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(ReconciliationFilterBuilder.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class));
@@ -166,10 +166,10 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
                     }
                 }
 
-                if (MappingItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz
-                        && !clazz.equals(JEXLMappingItemTransformerImpl.class)) {
+                if (ItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz
+                        && !clazz.equals(JEXLItemTransformerImpl.class)) {
 
-                    classNames.get(Type.MAPPING_ITEM_TRANSFORMER).add(clazz.getName());
+                    classNames.get(Type.ITEM_TRANSFORMER).add(clazz.getName());
                 }
 
                 if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbstractClazz

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
index c510677..a81a2d6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/ImplementationLookup.java
@@ -34,7 +34,7 @@ public interface ImplementationLookup extends SyncopeLoader {
         REPORTLET_CONF,
         ACCOUNT_RULE_CONF,
         PASSWORD_RULE_CONF,
-        MAPPING_ITEM_TRANSFORMER,
+        ITEM_TRANSFORMER,
         TASKJOBDELEGATE,
         RECONCILIATION_FILTER_BUILDER,
         LOGIC_ACTIONS,

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
index 5cefafb..de23601 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
@@ -34,6 +34,8 @@ public interface RealmDAO extends DAO<Realm> {
 
     Realm findByFullPath(String fullPath);
 
+    List<Realm> findByName(String name);
+
     List<Realm> findByResource(ExternalResource resource);
 
     <T extends Policy> List<Realm> findByPolicy(T policy);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
index 8b2cc2d..48ce512 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
@@ -133,7 +133,7 @@ public class LinkingMappingItem implements MappingItem {
     }
 
     @Override
-    public List<String> getMappingItemTransformerClassNames() {
+    public List<String> getTransformerClassNames() {
         return Collections.emptyList();
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
new file mode 100644
index 0000000..e8bf037
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.resource;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public interface Item extends Entity {
+
+    String getExtAttrName();
+
+    void setExtAttrName(String extAttrName);
+
+    String getIntAttrName();
+
+    void setIntAttrName(String intAttrName);
+
+    String getMandatoryCondition();
+
+    void setMandatoryCondition(String condition);
+
+    MappingPurpose getPurpose();
+
+    void setPurpose(MappingPurpose purpose);
+
+    boolean isConnObjectKey();
+
+    void setConnObjectKey(boolean connObjectKey);
+
+    boolean isPassword();
+
+    void setPassword(boolean password);
+
+    String getPropagationJEXLTransformer();
+
+    void setPropagationJEXLTransformer(String propagationJEXLTransformer);
+
+    String getPullJEXLTransformer();
+
+    void setPullJEXLTransformer(String pullJEXLTransformer);
+
+    List<String> getTransformerClassNames();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
index 5c14f18..92940a0 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
@@ -27,15 +27,15 @@ public interface Mapping extends Entity {
 
     void setProvision(Provision provision);
 
+    String getConnObjectLink();
+
+    void setConnObjectLink(String connObjectLink);
+
     boolean add(MappingItem item);
 
     MappingItem getConnObjectKeyItem();
 
     void setConnObjectKeyItem(MappingItem item);
 
-    String getConnObjectLink();
-
-    void setConnObjectLink(String connObjectLink);
-
     List<? extends MappingItem> getItems();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
index 461eaa1..24dc15d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
@@ -18,48 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.entity.resource;
 
-import java.util.List;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-
-public interface MappingItem extends Entity {
+public interface MappingItem extends Item {
 
     Mapping getMapping();
 
     void setMapping(Mapping mapping);
 
-    String getExtAttrName();
-
-    void setExtAttrName(String extAttrName);
-
-    String getIntAttrName();
-
-    void setIntAttrName(String intAttrName);
-
-    String getMandatoryCondition();
-
-    void setMandatoryCondition(String condition);
-
-    MappingPurpose getPurpose();
-
-    void setPurpose(MappingPurpose purpose);
-
-    boolean isConnObjectKey();
-
-    void setConnObjectKey(boolean connObjectKey);
-
-    boolean isPassword();
-
-    void setPassword(boolean password);
-
-    String getPropagationJEXLTransformer();
-
-    void setPropagationJEXLTransformer(String propagationJEXLTransformer);
-
-    String getPullJEXLTransformer();
-
-    void setPullJEXLTransformer(String pullJEXLTransformer);
-
-    List<String> getMappingItemTransformerClassNames();
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
index da8bee1..cdb0504 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity.resource;
 
+import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.SyncToken;
@@ -38,12 +39,15 @@ public interface OrgUnit extends Entity {
 
     void setSyncToken(SyncToken syncToken);
 
-    String getExtAttrName();
-
-    void setExtAttrName(String extAttrName);
-
     String getConnObjectLink();
 
     void setConnObjectLink(String connObjectLink);
 
+    boolean add(OrgUnitItem item);
+
+    OrgUnitItem getConnObjectKeyItem();
+
+    void setConnObjectKeyItem(OrgUnitItem item);
+
+    List<? extends OrgUnitItem> getItems();
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index 87cd26f..0f4cb62 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -63,6 +63,7 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
         return result;
     }
 
+    @Transactional(readOnly = true)
     @Override
     public Realm find(final String key) {
         return entityManager().find(JPARealm.class, key);
@@ -118,6 +119,15 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
     }
 
     @Override
+    public List<Realm> findByName(final String name) {
+        TypedQuery<Realm> query = entityManager().createQuery("SELECT e FROM " + JPARealm.class.getSimpleName() + " e "
+                + "WHERE e.name=:name", Realm.class);
+        query.setParameter("name", name);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<Realm> findByResource(final ExternalResource resource) {
         TypedQuery<Realm> query = entityManager().createQuery("SELECT e FROM " + JPARealm.class.getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources", Realm.class);
@@ -186,6 +196,7 @@ public class JPARealmDAO extends AbstractDAO<Realm> implements RealmDAO {
         return result;
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<Realm> findAll() {
         return findDescendants(getRoot());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 88f4e5a..66894e5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -127,7 +127,9 @@ import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnit;
 import org.apache.syncope.core.persistence.api.entity.DynRealm;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnitItem;
 
 @Component
 public class JPAEntityFactory implements EntityFactory {
@@ -219,6 +221,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPAMapping();
         } else if (reference.equals(MappingItem.class)) {
             result = (E) new JPAMappingItem();
+        } else if (reference.equals(OrgUnitItem.class)) {
+            result = (E) new JPAOrgUnitItem();
         } else if (reference.equals(GPlainAttr.class)) {
             result = (E) new JPAGPlainAttr();
         } else if (reference.equals(GPlainAttrValue.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
new file mode 100644
index 0000000..5bb91b9
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.resource;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.MappedSuperclass;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+
+@MappedSuperclass
+public abstract class AbstractItem extends AbstractGeneratedKeyEntity implements Item {
+
+    private static final long serialVersionUID = 5552380143129988272L;
+
+    @NotNull
+    private String intAttrName;
+
+    /**
+     * Target resource's field to be mapped.
+     */
+    @NotNull
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    @NotNull
+    private String mandatoryCondition;
+
+    /**
+     * Specify if the mapped target resource's field is the id.
+     */
+    @NotNull
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    @NotNull
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer password;
+
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    private MappingPurpose purpose;
+
+    /**
+     * (Optional) JEXL expression to apply to values before propagation.
+     */
+    @Column(name = "propJEXL")
+    private String propagationJEXLTransformer;
+
+    /**
+     * (Optional) JEXL expression to apply to values before pull.
+     */
+    @Column(name = "pullJEXL")
+    private String pullJEXLTransformer;
+
+    public AbstractItem() {
+        super();
+
+        mandatoryCondition = Boolean.FALSE.toString();
+
+        connObjectKey = getBooleanAsInteger(false);
+        password = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    @Override
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    @Override
+    public void setMandatoryCondition(final String mandatoryCondition) {
+        this.mandatoryCondition = mandatoryCondition;
+    }
+
+    @Override
+    public String getIntAttrName() {
+        return intAttrName;
+    }
+
+    @Override
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    @Override
+    public boolean isConnObjectKey() {
+        return isBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = getBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public boolean isPassword() {
+        return isBooleanAsInteger(password);
+    }
+
+    @Override
+    public void setPassword(final boolean password) {
+        this.password = getBooleanAsInteger(password);
+    }
+
+    @Override
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    @Override
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+
+    @Override
+    public String getPropagationJEXLTransformer() {
+        return propagationJEXLTransformer;
+    }
+
+    @Override
+    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
+        this.propagationJEXLTransformer = propagationJEXLTransformer;
+    }
+
+    @Override
+    public String getPullJEXLTransformer() {
+        return pullJEXLTransformer;
+    }
+
+    @Override
+    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
+        this.pullJEXLTransformer = pullJEXLTransformer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
index 3894994..bac3955 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -27,7 +27,6 @@ import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
@@ -44,8 +43,7 @@ public class JPAMapping extends AbstractGeneratedKeyEntity implements Mapping {
 
     public static final String TABLE = "Mapping";
 
-    @NotNull
-    @OneToOne
+    @OneToOne(optional = false)
     private JPAProvision provision;
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
index 47dac59..8624a70 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -20,30 +20,22 @@ package org.apache.syncope.core.persistence.jpa.entity.resource;
 
 import java.util.ArrayList;
 import java.util.List;
-import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import javax.validation.constraints.NotNull;
-import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
 
 @Entity
 @Table(name = JPAMappingItem.TABLE)
 @Cacheable
-public class JPAMappingItem extends AbstractGeneratedKeyEntity implements MappingItem {
+public class JPAMappingItem extends AbstractItem implements MappingItem {
 
     private static final long serialVersionUID = 7383601853619332424L;
 
@@ -52,73 +44,15 @@ public class JPAMappingItem extends AbstractGeneratedKeyEntity implements Mappin
     @ManyToOne
     private JPAMapping mapping;
 
-    @NotNull
-    private String intAttrName;
-
-    /**
-     * Target resource's field to be mapped.
-     */
-    @NotNull
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    @NotNull
-    private String mandatoryCondition;
-
-    /**
-     * Specify if the mapped target resource's field is the id.
-     */
-    @NotNull
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer connObjectKey;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    @NotNull
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer password;
-
-    @NotNull
-    @Enumerated(EnumType.STRING)
-    private MappingPurpose purpose;
-
-    /**
-     * (Optional) JEXL expression to apply to values before propagation.
-     */
-    @Column(name = "propJEXL")
-    private String propagationJEXLTransformer;
-
-    /**
-     * (Optional) JEXL expression to apply to values before pull.
-     */
-    @Column(name = "pullJEXL")
-    private String pullJEXLTransformer;
-
     /**
      * (Optional) classes for MappingItem transformation.
      */
     @ElementCollection(fetch = FetchType.EAGER)
     @Column(name = "transformerClassName")
-    @CollectionTable(name = "MappingItem_Transformer",
+    @CollectionTable(name = TABLE + "_Transformer",
             joinColumns =
             @JoinColumn(name = "mappingItem_id", referencedColumnName = "id"))
-    private List<String> mappingItemTransformerClassNames = new ArrayList<>();
-
-    public JPAMappingItem() {
-        super();
-
-        mandatoryCondition = Boolean.FALSE.toString();
-
-        connObjectKey = getBooleanAsInteger(false);
-        password = getBooleanAsInteger(false);
-    }
+    private List<String> transformerClassNames = new ArrayList<>();
 
     @Override
     public Mapping getMapping() {
@@ -132,88 +66,7 @@ public class JPAMappingItem extends AbstractGeneratedKeyEntity implements Mappin
     }
 
     @Override
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
     }
-
-    @Override
-    public String getIntAttrName() {
-        return intAttrName;
-    }
-
-    @Override
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    @Override
-    public boolean isConnObjectKey() {
-        return isBooleanAsInteger(connObjectKey);
-    }
-
-    @Override
-    public void setConnObjectKey(final boolean connObjectKey) {
-        this.connObjectKey = getBooleanAsInteger(connObjectKey);
-    }
-
-    @Override
-    public boolean isPassword() {
-        return isBooleanAsInteger(password);
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        this.password = getBooleanAsInteger(password);
-    }
-
-    @Override
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-
-    @Override
-    public String getPropagationJEXLTransformer() {
-        return propagationJEXLTransformer;
-    }
-
-    @Override
-    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
-        this.propagationJEXLTransformer = propagationJEXLTransformer;
-    }
-
-    @Override
-    public String getPullJEXLTransformer() {
-        return pullJEXLTransformer;
-    }
-
-    @Override
-    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
-        this.pullJEXLTransformer = pullJEXLTransformer;
-    }
-
-    @Override
-    public List<String> getMappingItemTransformerClassNames() {
-        return mappingItemTransformerClassNames;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
index 7324bfc..ab4398d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
@@ -18,13 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.resource;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Lob;
+import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@@ -50,11 +58,11 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit {
     private String serializedSyncToken;
 
     @NotNull
-    private String extAttrName;
-
-    @NotNull
     private String connObjectLink;
 
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "orgUnit")
+    private List<JPAOrgUnitItem> items = new ArrayList<>();
+
     @Override
     public ExternalResource getResource() {
         return resource;
@@ -96,23 +104,40 @@ public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit {
     }
 
     @Override
-    public String getExtAttrName() {
-        return extAttrName;
+    public String getConnObjectLink() {
+        return connObjectLink;
     }
 
     @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
+    public void setConnObjectLink(final String connObjectLink) {
+        this.connObjectLink = connObjectLink;
     }
 
     @Override
-    public String getConnObjectLink() {
-        return connObjectLink;
+    public boolean add(final OrgUnitItem item) {
+        checkType(item, JPAOrgUnitItem.class);
+        return items.contains((JPAOrgUnitItem) item) || items.add((JPAOrgUnitItem) item);
     }
 
     @Override
-    public void setConnObjectLink(final String connObjectLink) {
-        this.connObjectLink = connObjectLink;
+    public List<? extends OrgUnitItem> getItems() {
+        return items;
+    }
+
+    @Override
+    public OrgUnitItem getConnObjectKeyItem() {
+        return IterableUtils.find(getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.isConnObjectKey();
+            }
+        });
     }
 
+    @Override
+    public void setConnObjectKeyItem(final OrgUnitItem item) {
+        item.setConnObjectKey(true);
+        this.add(item);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
new file mode 100644
index 0000000..e356ff2
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
+
+@Entity
+@Table(name = JPAOrgUnitItem.TABLE)
+@Cacheable
+public class JPAOrgUnitItem extends AbstractItem implements OrgUnitItem {
+
+    private static final long serialVersionUID = 7872073846646341777L;
+
+    public static final String TABLE = "OrgUnitItem";
+
+    @ManyToOne
+    private JPAOrgUnit orgUnit;
+
+    /**
+     * (Optional) classes for MappingItem transformation.
+     */
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "transformerClassName")
+    @CollectionTable(name = TABLE + "_Transformer",
+            joinColumns =
+            @JoinColumn(name = "orgUnitItem_id", referencedColumnName = "id"))
+    private List<String> transformerClassNames = new ArrayList<>();
+
+    @Override
+    public OrgUnit getOrgUnit() {
+        return orgUnit;
+    }
+
+    @Override
+    public void setOrgUnit(final OrgUnit mapping) {
+        checkType(mapping, JPAOrgUnit.class);
+        this.orgUnit = (JPAOrgUnit) mapping;
+    }
+
+    @Override
+    public List<String> getTransformerClassNames() {
+        return transformerClassNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 80f4d6e..719a240 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.collections4.IterableUtils;
@@ -26,24 +27,22 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class ExternalResourceValidator extends AbstractValidator<ExternalResourceCheck, ExternalResource> {
 
-    private boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
-        if (mapping == null) {
-            return true;
-        }
-
-        long connObjectKeys = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
+    private boolean isValid(final List<? extends Item> items, final ConstraintValidatorContext context) {
+        long connObjectKeys = IterableUtils.countMatches(items, new Predicate<Item>() {
 
             @Override
-            public boolean evaluate(final MappingItem item) {
+            public boolean evaluate(final Item item) {
                 return item.isConnObjectKey();
             }
         });
@@ -56,36 +55,22 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
 
         boolean isValid = true;
 
-        long passwords = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
-
-            @Override
-            public boolean evaluate(final MappingItem item) {
-                return item.isPassword();
-            }
-        });
-        if (passwords > 1) {
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
-                    addPropertyNode("password.size").addConstraintViolation();
-            isValid = false;
-        }
-
-        for (MappingItem item : mapping.getItems()) {
-            for (String className : item.getMappingItemTransformerClassNames()) {
+        for (Item item : items) {
+            for (String className : item.getTransformerClassNames()) {
                 Class<?> actionsClass = null;
                 boolean isAssignable = false;
                 try {
                     actionsClass = Class.forName(className);
-                    isAssignable = MappingItemTransformer.class.isAssignableFrom(actionsClass);
+                    isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass);
                 } catch (Exception e) {
-                    LOG.error("Invalid MappingItemTransformer specified: {}", className, e);
+                    LOG.error("Invalid ItemTransformer specified: {}", className, e);
                 }
 
                 if (actionsClass == null || !isAssignable) {
                     context.buildConstraintViolationWithTemplate(
                             getTemplate(EntityViolationType.InvalidMapping,
-                                    "Invalid mapping item trasformer class name")).
-                            addPropertyNode("mappingItemTransformerClassName").addConstraintViolation();
+                                    "Invalid item trasformer class name")).
+                            addPropertyNode("itemTransformerClassName").addConstraintViolation();
                     isValid = false;
                 }
             }
@@ -94,6 +79,38 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
         return isValid;
     }
 
+    private boolean isValid(final OrgUnit orgUnit, final ConstraintValidatorContext context) {
+        if (orgUnit == null) {
+            return true;
+        }
+
+        return isValid(orgUnit.getItems(), context);
+    }
+
+    private boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
+        if (mapping == null) {
+            return true;
+        }
+
+        boolean isValid = true;
+
+        long passwords = IterableUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.isPassword();
+            }
+        });
+        if (passwords > 1) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
+                    addPropertyNode("password.size").addConstraintViolation();
+            isValid = false;
+        }
+
+        return isValid && isValid(mapping.getItems(), context);
+    }
+
     @Override
     public boolean isValid(final ExternalResource resource, final ConstraintValidatorContext context) {
         context.disableDefaultConstraintViolation();
@@ -138,6 +155,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
                 return isValid(provision.getMapping(), context);
             }
         });
+        validMappings &= isValid(resource.getOrgUnit(), context);
 
         if (anyTypes.size() < resource.getProvisions().size()) {
             context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index b88aee1..0e1598e 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -799,10 +799,16 @@ under the License.
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["entryUUID"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":true,"order":7,"confidential":false,"defaultValues":[]},"overridable":true,"values":["o=isp"]}]'/>
+                    jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":true,"order":7,"confidential":false,"defaultValues":[]},"overridable":true,"values":["o=isp"]}]'/>
   <OrgUnit id="599a59cf-9a23-4447-9a59-cf9a2334473a" connObjectLink="syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'"
-           extAttrName="ou" objectClass="organizationalUnit" resource_id="resource-ldap-orgunit"/>
-
+           objectClass="organizationalUnit" resource_id="resource-ldap-orgunit"/>
+  <OrgUnitItem id="5d0e7ad0-9026-42ad-be8a-32539389e7bd" connObjectKey="1" extAttrName="l"
+               intAttrName="fullpath" mandatoryCondition="true" purpose="BOTH"
+               orgUnit_id="599a59cf-9a23-4447-9a59-cf9a2334473a"/>
+  <OrgUnitItem id="1df556d3-bc23-48b7-a09b-fc3794a00019" connObjectKey="0" extAttrName="ou"
+               intAttrName="name" mandatoryCondition="true" purpose="BOTH"
+               orgUnit_id="599a59cf-9a23-4447-9a59-cf9a2334473a"/>
+  
   <ExternalResource id="ws-target-resource-nopropagation" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
index 8d0be03..daa09e2 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
@@ -22,10 +22,14 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 
@@ -41,6 +45,15 @@ public interface MappingManager {
     String getConnObjectKeyValue(Any<?> any, Provision provision);
 
     /**
+     * Get connObjectKey internal value.
+     *
+     * @param realm realm
+     * @param orgUnit orgUnit information
+     * @return connObjectKey internal value
+     */
+    String getConnObjectKeyValue(Realm realm, OrgUnit orgUnit);
+
+    /**
      * Get attribute values for the given {@link MappingItem} and any object.
      *
      * @param provision provision information
@@ -65,6 +78,15 @@ public interface MappingManager {
             Any<?> any, String password, boolean changePwd, Boolean enable, Provision provision);
 
     /**
+     * Prepare attributes for sending to a connector instance.
+     *
+     * @param realm Realm
+     * @param orgUnit provision information
+     * @return connObjectLink + prepared attributes
+     */
+    Pair<String, Set<Attribute>> prepareAttrs(Realm realm, OrgUnit orgUnit);
+
+    /**
      * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
      * connector.
      *
@@ -76,4 +98,14 @@ public interface MappingManager {
      */
     <T extends AnyTO> void setIntValues(MappingItem mapItem, Attribute attr, T anyTO, AnyUtils anyUtils);
 
+    /**
+     * Set attribute values, according to the given {@link OrgUnitItem}, to realm from attribute received from
+     * connector.
+     *
+     * @param orgUnitItem mapping item
+     * @param attr attribute received from connector
+     * @param realmTO realm
+     */
+    void setIntValues(OrgUnitItem orgUnitItem, Attribute attr, RealmTO realmTO);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
new file mode 100644
index 0000000..1ec16c3
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+
+/**
+ * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter)
+ * the Syncope internal storage.
+ *
+ * These transformations are not applied to virtual attribute values.
+ */
+public interface ItemTransformer {
+
+    /**
+     * Invoked while preparing attribute values to be sent out to external resource during propagation.
+     *
+     * @param item mapping item
+     * @param entity entity
+     * @param values original values
+     * @return transformed values
+     */
+    List<PlainAttrValue> beforePropagation(
+            Item item,
+            Entity entity,
+            List<PlainAttrValue> values);
+
+    /**
+     * Invoked while reading attribute values from external resource during pull.
+     *
+     * @param item mapping item
+     * @param entityTO entity
+     * @param values original values
+     * @return transformed values
+     */
+    List<Object> beforePull(
+            Item item,
+            EntityTO entityTO,
+            List<Object> values);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
new file mode 100644
index 0000000..3194454
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLItemTransformer.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+/**
+ * {@link ItemTransformer} implementing evaluation of JEXL expression defined for a given
+ * {@link org.apache.syncope.core.persistence.api.entity.resource.MappingItem}.
+ */
+public interface JEXLItemTransformer extends ItemTransformer {
+
+    void setPropagationJEXL(String propagationJEXL);
+
+    void setPullJEXL(String pullJEXL);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
deleted file mode 100644
index 8717e3d..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/JEXLMappingItemTransformer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.data;
-
-/**
- * {@link MappingItemTransformer} implementing evaluation of JEXL expression defined for a given
- * {@link org.apache.syncope.core.persistence.api.entity.resource.MappingItem}.
- */
-public interface JEXLMappingItemTransformer extends MappingItemTransformer {
-
-    void setPropagationJEXL(String propagationJEXL);
-
-    void setPullJEXL(String pullJEXL);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
deleted file mode 100644
index d8cb012..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/MappingItemTransformer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api.data;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-
-/**
- * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter)
- * the Syncope internal storage.
- *
- * These transformations are not applied to virtual attribute values.
- */
-public interface MappingItemTransformer {
-
-    /**
-     * Invoked while preparing attribute values to be sent out to external resource during propagation.
-     *
-     * @param mappingItem mapping item
-     * @param any any object
-     * @param values original values
-     * @return transformed values
-     */
-    List<PlainAttrValue> beforePropagation(
-            MappingItem mappingItem,
-            Any<?> any,
-            List<PlainAttrValue> values);
-
-    /**
-     * Invoked while reading attribute values from external resource during pull.
-     *
-     * @param mappingItem mapping item
-     * @param anyTO any object
-     * @param values original values
-     * @return transformed values
-     */
-    List<Object> beforePull(
-            MappingItem mappingItem,
-            AnyTO anyTO,
-            List<Object> values);
-}


[07/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
index 81f94b9..4209734 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java
@@ -53,7 +53,7 @@ import org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddress
 import org.apache.syncope.core.persistence.jpa.dao.DefaultAccountRule;
 import org.apache.syncope.core.persistence.jpa.dao.DefaultPasswordRule;
 import org.apache.syncope.core.provisioning.java.DefaultLogicActions;
-import org.apache.syncope.core.provisioning.java.data.DefaultMappingItemTransformer;
+import org.apache.syncope.core.provisioning.java.data.DefaultItemTransformer;
 import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
 import org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions;
 import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
@@ -99,9 +99,9 @@ public class ITImplementationLookup implements ImplementationLookup {
             put(Type.PASSWORD_RULE_CONF, classNames);
 
             classNames = new HashSet<>();
-            classNames.add(PrefixMappingItemTransformer.class.getName());
-            classNames.add(DefaultMappingItemTransformer.class.getName());
-            put(Type.MAPPING_ITEM_TRANSFORMER, classNames);
+            classNames.add(PrefixItemTransformer.class.getName());
+            classNames.add(DefaultItemTransformer.class.getName());
+            put(Type.ITEM_TRANSFORMER, classNames);
 
             classNames = new HashSet<>();
             classNames.add(TestSampleJobDelegate.class.getName());

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
new file mode 100644
index 0000000..80a386e
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixItemTransformer.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.java.data.DefaultItemTransformer;
+
+public class PrefixItemTransformer extends DefaultItemTransformer {
+
+    public static final String PREFIX = "PREFIX_";
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item,
+            final Entity entity,
+            final List<PlainAttrValue> values) {
+
+        if (values == null || values.isEmpty() || values.get(0).getStringValue() == null) {
+            return super.beforePropagation(item, entity, values);
+        } else {
+            String value = values.get(0).getStringValue();
+            values.get(0).setStringValue(PREFIX + value);
+
+            return values;
+        }
+    }
+
+    @Override
+    public List<Object> beforePull(
+            final Item item,
+            final EntityTO entityTO,
+            final List<Object> values) {
+
+        if (values == null || values.isEmpty() || values.get(0) == null) {
+            return super.beforePull(item, entityTO, values);
+        } else {
+            List<Object> newValues = new ArrayList<>(values);
+            newValues.set(0, StringUtils.substringAfter(values.get(0).toString(), PREFIX));
+
+            return newValues;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
deleted file mode 100644
index 822860f..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/PrefixMappingItemTransformer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.fit.core.reference;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.java.data.DefaultMappingItemTransformer;
-
-public class PrefixMappingItemTransformer extends DefaultMappingItemTransformer {
-
-    public static final String PREFIX = "PREFIX_";
-
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        if (values == null || values.isEmpty() || values.get(0).getStringValue() == null) {
-            return super.beforePropagation(mappingItem, any, values);
-        } else {
-            String value = values.get(0).getStringValue();
-            values.get(0).setStringValue(PREFIX + value);
-
-            return values;
-        }
-    }
-
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        if (values == null || values.isEmpty() || values.get(0) == null) {
-            return super.beforePull(mappingItem, anyTO, values);
-        } else {
-            List<Object> newValues = new ArrayList<>(values);
-            newValues.set(0, StringUtils.substringAfter(values.get(0).toString(), PREFIX));
-
-            return newValues;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
index c316741..72fa798 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java
@@ -79,10 +79,10 @@ public class TestPullActions extends DefaultPullActions {
     }
 
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         AttrPatch fullnamePatch = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
index 1945320..a57980a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BulkActionITCase.java
@@ -144,7 +144,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         FormTester formTester = TESTER.newFormTester(
                 TAB_PANEL + "outerObjectsRepeater:2:outer:form:content:status:firstLevelContainer:"
@@ -181,7 +181,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.SUSPENDED, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         // re-activate
         TESTER.clickLink("body:realmsLI:realms");
@@ -236,7 +236,7 @@ public class BulkActionITCase extends AbstractConsoleITCase {
 
         component = TESTER.getComponentFromLastRenderedPage(component.getPageRelativePath() + ":cells:1:cell:check");
         assertEquals(Status.ACTIVE, StatusBean.class.cast(component.getDefaultModelObject()).getStatus());
-        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResourceName());
+        assertEquals(resourceName, StatusBean.class.cast(component.getDefaultModelObject()).getResource());
 
         TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:2:outer:dialog:footer:buttons:0:button",
                 Constants.ON_CLICK);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index 66df83e..2ccfd7e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -181,22 +181,16 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(component.getPageRelativePath() + ":actions:actionRepeater:0:action:action");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:0:value:oldAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:1:value:oldAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:textField", null);
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:textField", "even");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:textField", "even");
 
         TESTER.clickLink("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
                 + "secondLevelContainer:back");
@@ -232,22 +226,16 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(component.getPageRelativePath() + ":actions:actionRepeater:0:action:action");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:field-label", "ou");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:oldAttribute:textField", "even");
+                + "secondLevelContainer:second:remoteObject:propView:4:value:oldAttribute:textField", "even");
 
         TESTER.assertLabel("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:field-label", "ou");
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:0:value:newAttribute:textField", null);
-
-        TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:1:value:newAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:field-label", "ou");
 
         TESTER.assertModelValue("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
-                + "secondLevelContainer:second:remoteObject:propView:2:value:newAttribute:textField", null);
+                + "secondLevelContainer:second:remoteObject:propView:4:value:newAttribute:textField", null);
 
         TESTER.clickLink("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:"
                 + "secondLevelContainer:back");

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
index 302441e..312b632 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
@@ -20,7 +20,6 @@ package org.apache.syncope.fit.console;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
@@ -113,41 +112,10 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(component.getPageRelativePath() + ":res", Constants.ON_CLICK);
         TESTER.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:provision");
 
-        // ------------------------------------------
-        // Check for realm provisioning feature availability (SYNCOPE-874)
-        // ------------------------------------------
-        FormTester formTester = TESTER.newFormTester("body:toggle:outerObjectsRepeater:3:outer:form");
-        formTester.setValue("content:aboutRealmProvison:enableRealmsProvision:checkboxField", true);
-
-        TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "enableRealmsProvision:checkboxField", Constants.ON_CHANGE);
-
-        assertNotNull(findComponentById(
-                "body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:realmsProvisionContainer",
-                "connObjectLink"));
-
-        TESTER.assertLabel("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "realmsProvisionContainer:connObjectLink:field-label", "Object Link");
-
-        formTester.setValue("content:aboutRealmProvison:enableRealmsProvision:checkboxField", false);
-
-        TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:"
-                + "enableRealmsProvision:checkboxField", Constants.ON_CHANGE);
-
-        try {
-            findComponentById(
-                    "body:toggle:outerObjectsRepeater:3:outer:form:content:aboutRealmProvison:realmsProvisionContainer",
-                    "connObjectLink");
-            fail();
-        } catch (NullPointerException e) {
-            // correct
-        }
-        // ------------------------------------------
-
         TESTER.clickLink("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
                 + "content:group:beans:0:actions:actionRepeater:0:action:action");
 
-        formTester = TESTER.newFormTester(
+        FormTester formTester = TESTER.newFormTester(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:wizard:form");
         formTester.submit("buttons:next");
 
@@ -155,11 +123,11 @@ public class TopologyITCase extends AbstractConsoleITCase {
                 + "container:content:wizard:form:view:mapping:mappingContainer:mappings:1", WebMarkupContainer.class);
 
         TESTER.executeAjaxEvent("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
-                + "content:wizard:form:view:mapping:mappingContainer:mappings:1:mappingItemTransformers:icon",
+                + "content:wizard:form:view:mapping:mappingContainer:mappings:1:itemTransformers:icon",
                 Constants.ON_CLICK);
 
         TESTER.clickLink("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:"
-                + "wizard:form:view:mapping:mappingContainer:mappings:0:mappingItemTransformers:alertsLink");
+                + "wizard:form:view:mapping:mappingContainer:mappings:0:itemTransformers:alertsLink");
 
         TESTER.assertComponent("body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
                 + "content:wizard:outerObjectsRepeater:0:outer:container:content:togglePanelContainer:"
@@ -203,7 +171,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         formTester = TESTER.newFormTester(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:content:wizard:form");
 
-        formTester.setValue("view:container:type:dropDownChoiceField", "0");
+        formTester.setValue("view:container:type:dropDownChoiceField", "1");
         formTester.setValue("view:container:clazz:textField", "__ACCOUNT__");
         formTester.submit("buttons:next");
         TESTER.assertNoErrorMessage();

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
index 5bed533..02e744f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java
@@ -52,7 +52,7 @@ import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceHistoryConfTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -754,7 +754,7 @@ public class ConnectorITCase extends AbstractITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO mapItem = new MappingItemTO();
+            ItemTO mapItem = new ItemTO();
             mapItem.setExtAttrName("uid");
             mapItem.setIntAttrName("userId");
             mapItem.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
index 857e371..f325534 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java
@@ -67,7 +67,7 @@ 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.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -948,13 +948,13 @@ public class GroupITCase extends AbstractITCase {
 
             MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
 
-            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
+            ItemTO connObjectKey = mapping.getConnObjectKeyItem();
             connObjectKey.setIntAttrName("displayProperty");
             connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
             mapping.setConnObjectKeyItem(connObjectKey);
             mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
 
-            MappingItemTO description = new MappingItemTO();
+            ItemTO description = new ItemTO();
             description.setIntAttrName("key");
             description.setExtAttrName("description");
             description.setPurpose(MappingPurpose.PROPAGATION);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
index 3c7f929..6a4abd1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PullTaskTO;
@@ -234,11 +234,11 @@ public class MembershipITCase extends AbstractITCase {
         ResourceTO newResource = resourceService.read(RESOURCE_NAME_DBPULL);
         newResource.setKey(getUUIDString());
 
-        MappingItemTO item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
-                new Predicate<MappingItemTO>() {
+        ItemTO item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
+                new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "firstname".equals(object.getIntAttrName());
             }
         });
@@ -248,10 +248,10 @@ public class MembershipITCase extends AbstractITCase {
         item.setPurpose(MappingPurpose.BOTH);
 
         item = IterableUtils.find(newResource.getProvision("USER").getMapping().getItems(),
-                new Predicate<MappingItemTO>() {
+                new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "fullname".equals(object.getIntAttrName());
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
index 36286e0..7600340 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MigrationITCase.java
@@ -38,7 +38,7 @@ import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
@@ -263,14 +263,14 @@ public class MigrationITCase extends AbstractTaskITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("username");
         item.setExtAttrName("username");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setPassword(true);
         item.setIntAttrName("password");
         item.setExtAttrName("__PASSWORD__");
@@ -278,56 +278,56 @@ public class MigrationITCase extends AbstractTaskITCase {
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_CIPHER_ALGORITHM);
         item.setExtAttrName("cipherAlgorithm");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("surname");
         item.setExtAttrName("surname");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("email");
         item.setExtAttrName("email");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("firstname");
         item.setExtAttrName("firstname");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("ctype");
         item.setExtAttrName("type");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("gender");
         item.setExtAttrName("gender");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("loginDate");
         item.setExtAttrName("loginDate");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_RESOURCES_SCHEMA);
         item.setExtAttrName("__RESOURCES__");
         item.setMandatoryCondition("false");
@@ -344,42 +344,42 @@ public class MigrationITCase extends AbstractTaskITCase {
         mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("name");
         item.setExtAttrName("name");
         item.setMandatoryCondition("true");
         item.setPurpose(MappingPurpose.PULL);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("show");
         item.setExtAttrName("show");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("title");
         item.setExtAttrName("title");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_RESOURCES_SCHEMA);
         item.setExtAttrName("__RESOURCES__");
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.PULL);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName(MIGRATION_MEMBERSHIPS_SCHEMA);
         item.setExtAttrName("__MEMBERSHIPS__");
         item.setMandatoryCondition("false");

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
index 8c11fb7..b28e257 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MultitenancyITCase.java
@@ -33,7 +33,7 @@ import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ProvisionTO;
@@ -151,13 +151,13 @@ public class MultitenancyITCase extends AbstractITCase {
             mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setIntAttrName("username");
             item.setExtAttrName("cn");
             item.setPurpose(MappingPurpose.BOTH);
             mapping.setConnObjectKeyItem(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setPassword(true);
             item.setIntAttrName("password");
             item.setExtAttrName("userPassword");
@@ -165,14 +165,14 @@ public class MultitenancyITCase extends AbstractITCase {
             item.setMandatoryCondition("true");
             mapping.add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("key");
             item.setPurpose(MappingPurpose.BOTH);
             item.setExtAttrName("sn");
             item.setMandatoryCondition("true");
             mapping.add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("email");
             item.setPurpose(MappingPurpose.BOTH);
             item.setExtAttrName("mail");

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
index 937c37b..f4aa9bf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -116,16 +116,16 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         ProvisionTO provision = resource.getProvision("PRINTER");
         assertNotNull(provision);
 
-        MappingItemTO mappingItem = IterableUtils.find(
-                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+        ItemTO mappingItem = IterableUtils.find(
+                provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "location".equals(object.getIntAttrName());
             }
         });
         assertNotNull(mappingItem);
-        assertTrue(mappingItem.getMappingItemTransformerClassNames().isEmpty());
+        assertTrue(mappingItem.getTransformerClassNames().isEmpty());
 
         String suffix = getUUIDString();
         mappingItem.setPropagationJEXLTransformer("value + '" + suffix + "'");

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index d1d85f8..c0ac469 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -61,7 +61,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
@@ -83,7 +83,7 @@ import org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions;
 import org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.fit.ActivitiDetector;
-import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
+import org.apache.syncope.fit.core.reference.PrefixItemTransformer;
 import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
 import org.apache.syncope.fit.core.reference.TestPullActions;
 import org.apache.syncope.fit.core.reference.TestPullRule;
@@ -417,17 +417,16 @@ public class PullTaskITCase extends AbstractTaskITCase {
         ProvisionTO provision = resource.getProvision("PRINTER");
         assertNotNull(provision);
 
-        MappingItemTO mappingItem = IterableUtils.find(
-                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+        ItemTO mappingItem = IterableUtils.find(provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO object) {
+            public boolean evaluate(final ItemTO object) {
                 return "location".equals(object.getIntAttrName());
             }
         });
         assertNotNull(mappingItem);
-        mappingItem.getMappingItemTransformerClassNames().clear();
-        mappingItem.getMappingItemTransformerClassNames().add(PrefixMappingItemTransformer.class.getName());
+        mappingItem.getTransformerClassNames().clear();
+        mappingItem.getTransformerClassNames().add(PrefixItemTransformer.class.getName());
 
         try {
             resourceService.update(resource);
@@ -443,7 +442,7 @@ public class PullTaskITCase extends AbstractTaskITCase {
             // 1. create printer on external resource
             AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("pull");
             String originalLocation = anyObjectTO.getPlainAttr("location").getValues().get(0);
-            assertFalse(originalLocation.startsWith(PrefixMappingItemTransformer.PREFIX));
+            assertFalse(originalLocation.startsWith(PrefixItemTransformer.PREFIX));
 
             anyObjectTO = createAnyObject(anyObjectTO).getEntity();
             assertNotNull(anyObjectTO);
@@ -453,9 +452,9 @@ public class PullTaskITCase extends AbstractTaskITCase {
             ConnObjectTO connObjectTO = resourceService.
                     readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
             assertFalse(anyObjectTO.getPlainAttr("location").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
+                    startsWith(PrefixItemTransformer.PREFIX));
             assertTrue(connObjectTO.getAttr("LOCATION").getValues().get(0).
-                    startsWith(PrefixMappingItemTransformer.PREFIX));
+                    startsWith(PrefixItemTransformer.PREFIX));
 
             // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
             PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
index 4ed4a52..fe62261 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
@@ -346,7 +346,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setExtAttrName("cn");
             item.setIntAttrName(schemaTO.getKey());
             item.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
index aa096a6..bbe9ac5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java
@@ -206,38 +206,54 @@ public class RealmITCase extends AbstractITCase {
         RealmTO childRealm = new RealmTO();
         childRealm.setName("child");
         childRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
+        RealmTO descendantRealm = new RealmTO();
+        descendantRealm.setName("test");
+        descendantRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
 
         // 2. check propagation
-        ProvisioningResult<RealmTO> result =
-                realmService.create("/", realm).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
-                });
-        ProvisioningResult<RealmTO> resultChild =
-                realmService.create("/test", childRealm).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
-                });
+        ProvisioningResult<RealmTO> result = realmService.create("/", realm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
         assertNotNull(result);
-        assertNotNull(resultChild);
         assertEquals(1, result.getPropagationStatuses().size());
-        assertEquals(1, resultChild.getPropagationStatuses().size());
         assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, result.getPropagationStatuses().get(0).getResource());
-        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
+
+        ProvisioningResult<RealmTO> resultChild = realmService.create("/test", childRealm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
+        assertNotNull(resultChild);
+        assertEquals(1, resultChild.getPropagationStatuses().size());
+        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUCCESS, resultChild.getPropagationStatuses().get(0).getStatus());
 
-        realm = result.getEntity();
+        ProvisioningResult<RealmTO> resultDescendant = realmService.create("/test/child", descendantRealm).readEntity(
+                new GenericType<ProvisioningResult<RealmTO>>() {
+        });
+        assertNotNull(resultDescendant);
+        assertEquals(1, resultDescendant.getPropagationStatuses().size());
+        assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultDescendant.getPropagationStatuses().get(0).getResource());
+        assertEquals(PropagationTaskExecStatus.SUCCESS, resultDescendant.getPropagationStatuses().get(0).getStatus());
 
         // 3. check on LDAP
-        assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
-
-        // 3.1. check on LDAP also child realm, it should be under test organizational unit
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,o=isp"));
-        assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNotNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
 
         // 4. remove realms
+        realmService.delete("/test/child/test");
         realmService.delete("/test/child");
-        realmService.delete(realm.getFullPath());
+        realmService.delete("/test");
 
         // 5. check on LDAP: both realms should be deleted
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
-        assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
+        assertNull(
+                getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
index e91b393..bfa5d80 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java
@@ -42,7 +42,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
@@ -78,19 +78,19 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setConnObjectKey(false);
@@ -134,20 +134,20 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("uid");
         item.setIntAttrName("userId");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setConnObjectKey(false);
@@ -193,7 +193,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
@@ -207,7 +207,7 @@ public class ResourceITCase extends AbstractITCase {
 
         mapping = new MappingTO();
         provisionTO.setMapping(mapping);
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("groupId");
         item.setConnObjectKey(true);
@@ -243,13 +243,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("email");
         // missing intAttrName ...
         mapping.add(item);
@@ -278,13 +278,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("usernane");
         // missing extAttrName ...
         mapping.add(item);
@@ -308,7 +308,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setConnObjectKey(true);
@@ -355,7 +355,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         // Update with an existing and already assigned mapping
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setKey("cc973ed6-d031-4790-adab-fc059ac0c818");
         item.setExtAttrName("test3");
         item.setIntAttrName("fullname");
@@ -364,13 +364,13 @@ public class ResourceITCase extends AbstractITCase {
 
         // Update defining new mappings
         for (int i = 4; i < 6; i++) {
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setExtAttrName("test" + i);
             item.setIntAttrName("fullname");
             item.setPurpose(MappingPurpose.BOTH);
             mapping.add(item);
         }
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("key");
         item.setConnObjectKey(true);
@@ -382,7 +382,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(actual);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
+        Collection<ItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(4, mapItems.size());
     }
@@ -465,9 +465,15 @@ public class ResourceITCase extends AbstractITCase {
 
         OrgUnitTO orgUnit = new OrgUnitTO();
         orgUnit.setConnObjectLink("'ou=' + name + ',o=isp'");
-        orgUnit.setExtAttrName("ou");
         orgUnit.setObjectClass("organizationalUnit");
 
+        ItemTO item = new ItemTO();
+        item.setIntAttrName("name");
+        item.setExtAttrName("ou");
+        item.setMandatoryCondition("true");
+        item.setPurpose(MappingPurpose.BOTH);
+        orgUnit.setConnObjectKeyItem(item);
+
         resourceTO.setOrgUnit(orgUnit);
         resourceService.update(resourceTO);
         assertNull(resourceTO.getPropagationPriority());
@@ -684,13 +690,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("name");
         item.setExtAttrName("cn");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("userOwner");
         item.setExtAttrName("owner");
         item.setPurpose(MappingPurpose.BOTH);
@@ -729,14 +735,14 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(item);
 
-        MappingItemTO item2 = new MappingItemTO();
+        ItemTO item2 = new ItemTO();
         item2.setConnObjectKey(false);
         item2.setIntAttrName("gender");
         item2.setExtAttrName("gender");
@@ -751,7 +757,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
         assertEquals(MappingPurpose.PROPAGATION,
                 actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
-        for (MappingItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
+        for (ItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
             if ("gender".equals(itemTO.getIntAttrName())) {
                 assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
             }
@@ -773,7 +779,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provision.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setPurpose(MappingPurpose.BOTH);
@@ -803,7 +809,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("key");
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
@@ -811,7 +817,7 @@ public class ResourceITCase extends AbstractITCase {
         mapping.setConnObjectKeyItem(item);
 
         // Add mapping for a not existing internal attribute
-        item = new MappingItemTO();
+        item = new ItemTO();
         item.setIntAttrName("locatio");
         item.setExtAttrName("location");
         item.setPurpose(MappingPurpose.BOTH);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index 6e4cbca..948c426 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -38,7 +38,7 @@ import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.to.SAML2RequestTO;
 import org.apache.syncope.common.rest.api.service.SAML2SPService;
@@ -150,7 +150,7 @@ public class SAML2ITCase extends AbstractITCase {
 
         ssoCircle.getMappingItems().clear();
 
-        MappingItemTO keyMapping = new MappingItemTO();
+        ItemTO keyMapping = new ItemTO();
         keyMapping.setIntAttrName("email");
         keyMapping.setExtAttrName("EmailAddress");
         ssoCircle.setConnObjectKeyItem(keyMapping);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
index a1ddb44..ff0d094 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
@@ -50,7 +50,7 @@ import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
 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.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -611,7 +611,7 @@ public class UserIssuesITCase extends AbstractITCase {
     public void issueSYNCOPE354() {
         // change resource-ldap group mapping for including uniqueMember (need for assertions below)
         ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+        for (ItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("description".equals(item.getExtAttrName())) {
                 item.setExtAttrName("uniqueMember");
             }
@@ -658,7 +658,7 @@ public class UserIssuesITCase extends AbstractITCase {
                 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
 
         // 6. restore original resource-ldap group mapping
-        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+        for (ItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("uniqueMember".equals(item.getExtAttrName())) {
                 item.setExtAttrName("description");
             }
@@ -905,7 +905,7 @@ public class UserIssuesITCase extends AbstractITCase {
 
         MappingTO ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // change purpose from NONE to BOTH
-        for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
+        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
                 itemTO.setPurpose(MappingPurpose.BOTH);
             }
@@ -918,7 +918,7 @@ public class UserIssuesITCase extends AbstractITCase {
         assertNotNull(newWs1);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
+        Collection<ItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(7, mapItems.size());
 
@@ -943,7 +943,7 @@ public class UserIssuesITCase extends AbstractITCase {
         // 4.  restore resource ws-target-resource-1 mapping
         ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // restore purpose from BOTH to NONE
-        for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
+        for (ItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
                 itemTO.setPurpose(MappingPurpose.NONE);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
index 933cc99..5297257 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -273,10 +273,10 @@ public class VirAttrITCase extends AbstractITCase {
         try {
             // remove this mapping
             CollectionUtils.filterInverse(csv.getProvisions().get(0).getMapping().getItems(),
-                    new Predicate<MappingItemTO>() {
+                    new Predicate<ItemTO>() {
 
                 @Override
-                public boolean evaluate(final MappingItemTO item) {
+                public boolean evaluate(final ItemTO item) {
                     return "email".equals(item.getIntAttrName());
                 }
             });
@@ -504,20 +504,20 @@ public class VirAttrITCase extends AbstractITCase {
             MappingTO mapping = new MappingTO();
             provisionTO.setMapping(mapping);
 
-            MappingItemTO item = new MappingItemTO();
+            ItemTO item = new ItemTO();
             item.setIntAttrName("fullname");
             item.setExtAttrName("ID");
             item.setPurpose(MappingPurpose.PROPAGATION);
             item.setConnObjectKey(true);
             mapping.setConnObjectKeyItem(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("username");
             item.setExtAttrName("USERNAME");
             item.setPurpose(MappingPurpose.PROPAGATION);
             mapping.getItems().add(item);
 
-            item = new MappingItemTO();
+            item = new ItemTO();
             item.setIntAttrName("groups[" + groupName + "].rvirtualdata");
             item.setExtAttrName("EMAIL");
             item.setPurpose(MappingPurpose.PROPAGATION);
@@ -630,10 +630,10 @@ public class VirAttrITCase extends AbstractITCase {
         try {
             ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name());
             assertNotNull(provision);
-            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
+            CollectionUtils.filterInverse(provision.getMapping().getItems(), new Predicate<ItemTO>() {
 
                 @Override
-                public boolean evaluate(final MappingItemTO item) {
+                public boolean evaluate(final ItemTO item) {
                     return "mail".equals(item.getExtAttrName());
                 }
             });


[03/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
index 9666804..b2907c4 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.api.pushpull;
 
 import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
@@ -132,19 +131,18 @@ public interface PullActions extends ProvisioningActions {
      * The entity is updated upon pull in case of the matching rule
      * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
      *
-     * @param <M> concrete any object
      * @param <P> any object modifications
      * @param profile profile of the pull being executed.
      * @param delta retrieved pull information
-     * @param any any object
+     * @param entityTO entity
      * @param anyPatch modification
      * @return pull information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure.
      */
-    <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+    <P extends AnyPatch> SyncDelta beforeUpdate(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            M any,
+            EntityTO entityTO,
             P anyPatch)
             throws JobExecutionException;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index 38c895e..54ada98 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -23,55 +23,60 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 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.GroupableRelatableTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.spring.security.Encryptor;
-import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 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.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.GroupableRelatable;
 import org.apache.syncope.core.persistence.api.entity.Membership;
+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.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 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.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+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.DerAttrHandler;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.identityconnectors.framework.common.FrameworkUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -82,7 +87,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.apache.syncope.common.lib.to.GroupableRelatableTO;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Component
 public class MappingManagerImpl implements MappingManager {
@@ -110,6 +115,9 @@ public class MappingManagerImpl implements MappingManager {
     private GroupDAO groupDAO;
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private DerAttrHandler derAttrHandler;
 
     @Autowired
@@ -145,7 +153,7 @@ public class MappingManagerImpl implements MappingManager {
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
 
-        for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(provision)) {
+        for (MappingItem mapItem : MappingUtils.getPropagationItems(provision)) {
             LOG.debug("Processing expression '{}'", mapItem.getIntAttrName());
 
             try {
@@ -164,7 +172,7 @@ public class MappingManagerImpl implements MappingManager {
                             attributes.remove(alreadyAdded);
 
                             Set<Object> values = new HashSet<>();
-                            if (alreadyAdded.getValue() != null && !alreadyAdded.getValue().isEmpty()) {
+                            if (CollectionUtils.isNotEmpty(alreadyAdded.getValue())) {
                                 values.addAll(alreadyAdded.getValue());
                             }
 
@@ -198,7 +206,75 @@ public class MappingManagerImpl implements MappingManager {
             }
         }
 
-        return new ImmutablePair<>(connObjectKey, attributes);
+        return Pair.of(connObjectKey, attributes);
+    }
+
+    private String getIntValue(final Realm realm, final OrgUnitItem orgUnitItem) {
+        String value = null;
+        switch (orgUnitItem.getIntAttrName()) {
+            case "key":
+                value = realm.getKey();
+                break;
+
+            case "name":
+                value = realm.getName();
+                break;
+
+            case "fullpath":
+                value = realm.getFullPath();
+                break;
+
+            default:
+        }
+
+        return value;
+    }
+
+    @Override
+    public Pair<String, Set<Attribute>> prepareAttrs(final Realm realm, final OrgUnit orgUnit) {
+        LOG.debug("Preparing resource attributes for {} with orgUnit {}", realm, orgUnit);
+
+        Set<Attribute> attributes = new HashSet<>();
+        String connObjectKey = null;
+
+        for (OrgUnitItem orgUnitItem : MappingUtils.getPropagationItems(orgUnit)) {
+            LOG.debug("Processing expression '{}'", orgUnitItem.getIntAttrName());
+
+            String value = getIntValue(realm, orgUnitItem);
+
+            if (orgUnitItem.isConnObjectKey()) {
+                connObjectKey = value;
+            }
+
+            Attribute alreadyAdded = AttributeUtil.find(orgUnitItem.getExtAttrName(), attributes);
+            if (alreadyAdded == null) {
+                if (value == null) {
+                    attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName()));
+                } else {
+                    attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), value));
+                }
+            } else if (value != null) {
+                attributes.remove(alreadyAdded);
+
+                Set<Object> values = new HashSet<>();
+                if (CollectionUtils.isNotEmpty(alreadyAdded.getValue())) {
+                    values.addAll(alreadyAdded.getValue());
+                }
+                values.add(value);
+
+                attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), values));
+            }
+        }
+
+        Attribute connObjectKeyExtAttr =
+                AttributeUtil.find(orgUnit.getConnObjectKeyItem().getExtAttrName(), attributes);
+        if (connObjectKeyExtAttr != null) {
+            attributes.remove(connObjectKeyExtAttr);
+            attributes.add(AttributeBuilder.build(orgUnit.getConnObjectKeyItem().getExtAttrName(), connObjectKey));
+        }
+        attributes.add(MappingUtils.evaluateNAME(realm, orgUnit, connObjectKey));
+
+        return Pair.of(connObjectKey, attributes);
     }
 
     /**
@@ -263,7 +339,7 @@ public class MappingManagerImpl implements MappingManager {
             }
 
             if (mapItem.isConnObjectKey()) {
-                result = new ImmutablePair<>(objValues.isEmpty() ? null : objValues.iterator().next().toString(), null);
+                result = Pair.of(objValues.isEmpty() ? null : objValues.iterator().next().toString(), null);
             } else if (mapItem.isPassword() && any instanceof User) {
                 String passwordAttrValue = password;
                 if (StringUtils.isBlank(passwordAttrValue)) {
@@ -286,15 +362,12 @@ public class MappingManagerImpl implements MappingManager {
                 if (passwordAttrValue == null) {
                     result = null;
                 } else {
-                    result = new ImmutablePair<>(
-                            null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
+                    result = Pair.of(null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
                 }
             } else if (schema != null && schema.isMultivalue()) {
-                result = new ImmutablePair<>(
-                        null, AttributeBuilder.build(mapItem.getExtAttrName(), objValues));
+                result = Pair.of(null, AttributeBuilder.build(mapItem.getExtAttrName(), objValues));
             } else {
-                result = new ImmutablePair<>(
-                        null, objValues.isEmpty()
+                result = Pair.of(null, objValues.isEmpty()
                         ? AttributeBuilder.build(mapItem.getExtAttrName())
                         : AttributeBuilder.build(mapItem.getExtAttrName(), objValues.iterator().next()));
             }
@@ -484,7 +557,7 @@ public class MappingManagerImpl implements MappingManager {
 
         List<PlainAttrValue> transformed = values;
         if (transform) {
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mapItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem)) {
                 transformed = transformer.beforePropagation(mapItem, any, transformed);
             }
             LOG.debug("Transformed values: {}", values);
@@ -519,13 +592,21 @@ public class MappingManagerImpl implements MappingManager {
 
     @Transactional(readOnly = true)
     @Override
+    public String getConnObjectKeyValue(final Realm realm, final OrgUnit orgUnit) {
+        OrgUnitItem orgUnitItem = orgUnit.getConnObjectKeyItem();
+
+        return getIntValue(realm, orgUnitItem);
+    }
+
+    @Transactional(readOnly = true)
+    @Override
     public void setIntValues(
             final MappingItem mapItem, final Attribute attr, final AnyTO anyTO, final AnyUtils anyUtils) {
 
         List<Object> values = null;
         if (attr != null) {
             values = attr.getValue();
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mapItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem)) {
                 values = transformer.beforePull(mapItem, anyTO, values);
             }
         }
@@ -679,4 +760,36 @@ public class MappingManagerImpl implements MappingManager {
             }
         }
     }
+
+    @Override
+    public void setIntValues(final OrgUnitItem orgUnitItem, final Attribute attr, final RealmTO realmTO) {
+        List<Object> values = null;
+        if (attr != null) {
+            values = attr.getValue();
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(orgUnitItem)) {
+                values = transformer.beforePull(orgUnitItem, realmTO, values);
+            }
+        }
+
+        if (values != null && !values.isEmpty() && values.get(0) != null) {
+            switch (orgUnitItem.getIntAttrName()) {
+                case "name":
+                    realmTO.setName(values.get(0).toString());
+                    break;
+
+                case "fullpath":
+                    String parentFullPath = StringUtils.substringBeforeLast(values.get(0).toString(), "/");
+                    Realm parent = realmDAO.findByFullPath(parentFullPath);
+                    if (parent == null) {
+                        LOG.warn("Could not find Realm with path {}, ignoring", parentFullPath);
+                    } else {
+                        realmTO.setParent(parent.getFullPath());
+                    }
+                    break;
+
+                default:
+            }
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/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 b25712b..108b530 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
@@ -226,7 +226,7 @@ abstract class AbstractAnyDataBinder {
     private List<String> evaluateMandatoryCondition(final Provision provision, final Any<?> any) {
         List<String> missingAttrNames = new ArrayList<>();
 
-        for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(provision)) {
+        for (MappingItem mapItem : MappingUtils.getPropagationItems(provision)) {
             IntAttrName intAttrName =
                     intAttrNameParser.parse(mapItem.getIntAttrName(), provision.getAnyType().getKind());
             if (intAttrName.getSchemaType() != null) {
@@ -346,7 +346,7 @@ abstract class AbstractAnyDataBinder {
         }
 
         for (ExternalResource resource : resources) {
-            for (MappingItem item : MappingUtils.getPropagationMappingItems(resource.getProvision(any.getType()))) {
+            for (MappingItem item : MappingUtils.getPropagationItems(resource.getProvision(any.getType()))) {
                 if (schema.getKey().equals(item.getIntAttrName())) {
                     propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
new file mode 100644
index 0000000..230962a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Default (empty) implementation of {@link ItemTransformer}.
+ */
+@Transactional(readOnly = true)
+public class DefaultItemTransformer implements ItemTransformer {
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item, final Entity entity, final List<PlainAttrValue> values) {
+
+        return values;
+    }
+
+    @Override
+    public List<Object> beforePull(final Item item, final EntityTO entityTO, final List<Object> values) {
+        return values;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
deleted file mode 100644
index 37a471c..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Default (empty) implementation of {@link MappingItemTransformer}.
- */
-public class DefaultMappingItemTransformer implements MappingItemTransformer {
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        return values;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        return values;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
new file mode 100644
index 0000000..ae31618
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
+
+public class JEXLItemTransformerImpl extends DefaultItemTransformer implements JEXLItemTransformer {
+
+    private String propagationJEXL;
+
+    private String pullJEXL;
+
+    @Override
+    public void setPropagationJEXL(final String propagationJEXL) {
+        this.propagationJEXL = propagationJEXL;
+    }
+
+    @Override
+    public void setPullJEXL(final String pullJEXL) {
+        this.pullJEXL = pullJEXL;
+    }
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item,
+            final Entity entity,
+            final List<PlainAttrValue> values) {
+
+        if (StringUtils.isNotBlank(propagationJEXL) && values != null) {
+            for (PlainAttrValue value : values) {
+                JexlContext jexlContext = new MapContext();
+                if (entity != null) {
+                    JexlUtils.addFieldsToContext(entity, jexlContext);
+                    if (entity instanceof Any) {
+                        JexlUtils.addPlainAttrsToContext(((Any<?>) entity).getPlainAttrs(), jexlContext);
+                        JexlUtils.addDerAttrsToContext(((Any<?>) entity), jexlContext);
+                    }
+                }
+                jexlContext.set("value", value.getValueAsString());
+
+                value.setStringValue(JexlUtils.evaluate(propagationJEXL, jexlContext));
+            }
+
+            return values;
+        }
+
+        return super.beforePropagation(item, entity, values);
+    }
+
+    @Override
+    public List<Object> beforePull(
+            final Item item,
+            final EntityTO entityTO,
+            final List<Object> values) {
+
+        if (StringUtils.isNotBlank(pullJEXL) && values != null) {
+            List<Object> newValues = new ArrayList<>(values.size());
+            for (Object value : values) {
+                JexlContext jexlContext = new MapContext();
+                jexlContext.set("value", value);
+                if (entityTO instanceof AnyTO) {
+                    newValues.add(JexlUtils.evaluate(pullJEXL, (AnyTO) entityTO, jexlContext));
+                } else {
+                    newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
+                }
+            }
+
+            return newValues;
+        }
+
+        return super.beforePull(item, entityTO, values);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
deleted file mode 100644
index 07618aa..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.JEXLMappingItemTransformer;
-import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
-
-public class JEXLMappingItemTransformerImpl
-        extends DefaultMappingItemTransformer implements JEXLMappingItemTransformer {
-
-    private String propagationJEXL;
-
-    private String pullJEXL;
-
-    @Override
-    public void setPropagationJEXL(final String propagationJEXL) {
-        this.propagationJEXL = propagationJEXL;
-    }
-
-    @Override
-    public void setPullJEXL(final String pullJEXL) {
-        this.pullJEXL = pullJEXL;
-    }
-
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        if (StringUtils.isNotBlank(propagationJEXL) && values != null) {
-            for (PlainAttrValue value : values) {
-                JexlContext jexlContext = new MapContext();
-                if (any != null) {
-                    JexlUtils.addFieldsToContext(any, jexlContext);
-                    JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
-                    JexlUtils.addDerAttrsToContext(any, jexlContext);
-                }
-                jexlContext.set("value", value.getValueAsString());
-
-                value.setStringValue(JexlUtils.evaluate(propagationJEXL, jexlContext));
-            }
-
-            return values;
-        }
-
-        return super.beforePropagation(mappingItem, any, values);
-    }
-
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        if (StringUtils.isNotBlank(pullJEXL) && values != null) {
-            List<Object> newValues = new ArrayList<>(values.size());
-            for (Object value : values) {
-                JexlContext jexlContext = new MapContext();
-                jexlContext.set("value", value);
-                if (anyTO == null) {
-                    newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
-                } else {
-                    newValues.add(JexlUtils.evaluate(pullJEXL, anyTO, jexlContext));
-                }
-            }
-
-            return newValues;
-        }
-
-        return super.beforePull(mappingItem, anyTO, values);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/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 e6293cf..ba6da63 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
@@ -27,7 +27,8 @@ import org.apache.commons.collections4.IteratorUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemContainerTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
@@ -58,7 +59,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
@@ -76,7 +79,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
     private static final Logger LOG = LoggerFactory.getLogger(ResourceDataBinder.class);
 
-    private static final String[] MAPPINGITEM_IGNORE_PROPERTIES = { "key", "mapping" };
+    private static final String[] ITEM_IGNORE_PROPERTIES = { "key", "mapping" };
 
     @Autowired
     private AnyTypeDAO anyTypeDAO;
@@ -126,7 +129,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             List<ExternalResourceHistoryConf> history = resourceHistoryConfDAO.findByEntity(resource);
             long maxHistorySize = confDAO.find("resource.conf.history.size", "10").getValues().get(0).getLongValue();
             if (maxHistorySize < history.size()) {
-            // always remove the last item since history was obtained  by a query with ORDER BY creation DESC
+                // always remove the last item since history was obtained  by a query with ORDER BY creation DESC
                 for (int i = 0; i < history.size() - maxHistorySize; i++) {
                     resourceHistoryConfDAO.delete(history.get(history.size() - 1).getKey());
                 }
@@ -275,19 +278,60 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             }
             orgUnit.setObjectClass(new ObjectClass(orgUnitTO.getObjectClass()));
 
-            if (orgUnitTO.getExtAttrName() == null) {
-                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
-                sce.getElements().add("Null extAttrName");
-                throw sce;
-            }
-            orgUnit.setExtAttrName(orgUnitTO.getExtAttrName());
-
             if (orgUnitTO.getConnObjectLink() == null) {
                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
                 sce.getElements().add("Null connObjectLink");
                 throw sce;
             }
             orgUnit.setConnObjectLink(orgUnitTO.getConnObjectLink());
+
+            SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+            SyncopeClientException invalidMapping = SyncopeClientException.build(
+                    ClientExceptionType.InvalidMapping);
+            SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
+                    ClientExceptionType.RequiredValuesMissing);
+
+            orgUnit.getItems().clear();
+            for (ItemTO itemTO : orgUnitTO.getItems()) {
+                if (itemTO == null) {
+                    LOG.error("Null {}", ItemTO.class.getSimpleName());
+                    invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
+                } else if (itemTO.getIntAttrName() == null) {
+                    requiredValuesMissing.getElements().add("intAttrName");
+                    scce.addException(requiredValuesMissing);
+                } else {
+                    if (!"name".equals(itemTO.getIntAttrName()) && !"fullpath".equals(itemTO.getIntAttrName())) {
+                        LOG.error("Only 'name' and 'fullpath' are supported for Realms");
+                        invalidMapping.getElements().add("Only 'name' and 'fullpath' are supported for Realms");
+                    } else {
+                        // no mandatory condition implies mandatory condition false
+                        if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
+                                ? "false" : itemTO.getMandatoryCondition())) {
+
+                            SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
+                                    ClientExceptionType.InvalidValues);
+                            invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
+                            scce.addException(invalidMandatoryCondition);
+                        }
+
+                        OrgUnitItem item = entityFactory.newEntity(OrgUnitItem.class);
+                        BeanUtils.copyProperties(itemTO, item, ITEM_IGNORE_PROPERTIES);
+                        item.setOrgUnit(orgUnit);
+                        if (item.isConnObjectKey()) {
+                            orgUnit.setConnObjectKeyItem(item);
+                        } else {
+                            orgUnit.add(item);
+                        }
+
+                    }
+                }
+            }
+            if (!invalidMapping.getElements().isEmpty()) {
+                scce.addException(invalidMapping);
+            }
+            if (scce.hasExceptions()) {
+                throw scce;
+            }
         }
 
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
@@ -328,10 +372,10 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
                 ClientExceptionType.RequiredValuesMissing);
 
-        for (MappingItemTO itemTO : mappingTO.getItems()) {
+        for (ItemTO itemTO : mappingTO.getItems()) {
             if (itemTO == null) {
-                LOG.error("Null {}", MappingItemTO.class.getSimpleName());
-                invalidMapping.getElements().add("Null " + MappingItemTO.class.getSimpleName());
+                LOG.error("Null {}", ItemTO.class.getSimpleName());
+                invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
             } else if (itemTO.getIntAttrName() == null) {
                 requiredValuesMissing.getElements().add("intAttrName");
                 scce.addException(requiredValuesMissing);
@@ -377,7 +421,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
                         }
 
                         MappingItem item = entityFactory.newEntity(MappingItem.class);
-                        BeanUtils.copyProperties(itemTO, item, MAPPINGITEM_IGNORE_PROPERTIES);
+                        BeanUtils.copyProperties(itemTO, item, ITEM_IGNORE_PROPERTIES);
                         item.setMapping(mapping);
                         if (item.isConnObjectKey()) {
                             if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) {
@@ -442,18 +486,16 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         }
     }
 
-    private void populateMappingTO(final Mapping mapping, final MappingTO mappingTO) {
-        mappingTO.setConnObjectLink(mapping.getConnObjectLink());
-
-        for (MappingItem item : mapping.getItems()) {
-            MappingItemTO itemTO = new MappingItemTO();
+    private void populateItems(final List<? extends Item> items, final ItemContainerTO containerTO) {
+        for (Item item : items) {
+            ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
-            BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+            BeanUtils.copyProperties(item, itemTO, ITEM_IGNORE_PROPERTIES);
 
             if (itemTO.isConnObjectKey()) {
-                mappingTO.setConnObjectKeyItem(itemTO);
+                containerTO.setConnObjectKeyItem(itemTO);
             } else {
-                mappingTO.add(itemTO);
+                containerTO.add(itemTO);
             }
         }
     }
@@ -484,7 +526,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             if (provision.getMapping() != null) {
                 MappingTO mappingTO = new MappingTO();
                 provisionTO.setMapping(mappingTO);
-                populateMappingTO(provision.getMapping(), mappingTO);
+                mappingTO.setConnObjectLink(provision.getMapping().getConnObjectLink());
+                populateItems(provision.getMapping().getItems(), mappingTO);
             }
 
             for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
@@ -492,9 +535,9 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
                 MappingItem linkingMappingItem = virSchema.asLinkingMappingItem();
 
-                MappingItemTO itemTO = new MappingItemTO();
+                ItemTO itemTO = new ItemTO();
                 itemTO.setKey(linkingMappingItem.getKey());
-                BeanUtils.copyProperties(linkingMappingItem, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+                BeanUtils.copyProperties(linkingMappingItem, itemTO, ITEM_IGNORE_PROPERTIES);
 
                 provisionTO.getMapping().getLinkingItems().add(itemTO);
             }
@@ -509,8 +552,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             orgUnitTO.setKey(orgUnit.getKey());
             orgUnitTO.setObjectClass(orgUnit.getObjectClass().getObjectClassValue());
             orgUnitTO.setSyncToken(orgUnit.getSerializedSyncToken());
-            orgUnitTO.setExtAttrName(orgUnit.getExtAttrName());
             orgUnitTO.setConnObjectLink(orgUnit.getConnObjectLink());
+            populateItems(orgUnit.getItems(), orgUnitTO);
 
             resourceTO.setOrgUnit(orgUnitTO);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/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 a14ba2f..b24c85c 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
@@ -51,9 +51,7 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
@@ -69,15 +67,12 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationException
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
 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.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder;
 import org.identityconnectors.framework.common.objects.Name;
 import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
 import org.identityconnectors.framework.common.objects.Uid;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -120,12 +115,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     protected GroupDAO groupDAO;
 
     /**
-     * Realm DAO.
-     */
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    /**
      * Task DAO.
      */
     @Autowired
@@ -396,7 +385,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                     ? null
                     : orgUnit == null
                             ? getRemoteObject(task, connector, provision, false)
-                            : getRemoteObject(task, connector, orgUnit);
+                            : getRemoteObject(task, connector, orgUnit, false);
 
             for (PropagationActions action : actions) {
                 action.before(task, beforeObj);
@@ -463,7 +452,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                             ? null
                             : orgUnit == null
                                     ? getRemoteObject(task, connector, provision, true)
-                                    : getRemoteObject(task, connector, orgUnit);
+                                    : getRemoteObject(task, connector, orgUnit, true);
                 } catch (Exception ignore) {
                     // ignore exception
                     LOG.error("Error retrieving after object", ignore);
@@ -621,7 +610,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
                     new Uid(connObjectKey),
                     MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
-                            MappingUtils.getPropagationMappingItems(provision).iterator(),
+                            MappingUtils.getPropagationItems(provision).iterator(),
                             linkingMappingItems.iterator())));
 
             for (MappingItem item : linkingMappingItems) {
@@ -650,37 +639,31 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
      * @param connector connector facade proxy.
      * @param task current propagation task.
      * @param orgUnit orgUnit
+     * @param latest 'FALSE' to retrieve object using old connObjectKey if not null.
      * @return remote connector object.
      */
     protected ConnectorObject getRemoteObject(
             final PropagationTask task,
             final Connector connector,
-            final OrgUnit orgUnit) {
+            final OrgUnit orgUnit,
+            final boolean latest) {
 
-        Realm realm = realmDAO.find(task.getEntityKey());
-        if (realm == null) {
-            return null;
-        }
+        String connObjectKey = latest || task.getOldConnObjectKey() == null
+                ? task.getConnObjectKey()
+                : task.getOldConnObjectKey();
 
-        final ConnectorObject[] obj = new ConnectorObject[1];
+        ConnectorObject obj = null;
         try {
-            connector.search(new ObjectClass(task.getObjectClassName()),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realm.getName())),
-                    new ResultsHandler() {
-
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
+            obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
+                    new Uid(connObjectKey),
+                    MappingUtils.buildOperationOptions(MappingUtils.getPropagationItems(orgUnit).iterator()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", task.getConnObjectKey(), ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
 
-        return obj[0];
+        return obj;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/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 f1ec799..c826f6b 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
@@ -28,8 +28,6 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
@@ -68,7 +66,6 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -204,8 +201,8 @@ public class PropagationManagerImpl implements PropagationManager {
         return getUpdateTasks(
                 userDAO.authFind(wfResult.getResult().getKey().getKey()),
                 wfResult.getResult().getKey().getPassword() == null
-                        ? null
-                        : wfResult.getResult().getKey().getPassword().getValue(),
+                ? null
+                : wfResult.getResult().getKey().getPassword().getValue(),
                 changePwd,
                 wfResult.getResult().getValue(),
                 wfResult.getPropByRes(),
@@ -381,9 +378,9 @@ public class PropagationManagerImpl implements PropagationManager {
         for (Map.Entry<String, ResourceOperation> entry : propByRes.asMap().entrySet()) {
             ExternalResource resource = resourceDAO.find(entry.getKey());
             Provision provision = resource == null ? null : resource.getProvision(any.getType());
-            List<MappingItem> mappingItems = provision == null
+            List<? extends MappingItem> mappingItems = provision == null
                     ? Collections.<MappingItem>emptyList()
-                    : MappingUtils.getPropagationMappingItems(provision);
+                    : MappingUtils.getPropagationItems(provision);
 
             if (resource == null) {
                 LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -484,28 +481,11 @@ public class PropagationManagerImpl implements PropagationManager {
                 task.setObjectClassName(orgUnit.getObjectClass().getObjectClassValue());
                 task.setEntityKey(realm.getKey());
                 task.setOperation(entry.getValue());
+                task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
-                Set<Attribute> preparedAttrs = new HashSet<>();
-                preparedAttrs.add(AttributeBuilder.build(orgUnit.getExtAttrName(), realm.getName()));
-
-                JexlContext jexlContext = new MapContext();
-                JexlUtils.addFieldsToContext(realm, jexlContext);
-                String evalConnObjectLink = JexlUtils.evaluate(orgUnit.getConnObjectLink(), jexlContext);
-                if (StringUtils.isBlank(evalConnObjectLink)) {
-                    // add connObjectKey as __NAME__ attribute ...
-                    LOG.debug("Add connObjectKey [{}] as __NAME__", realm.getName());
-                    preparedAttrs.add(new Name(realm.getName()));
-                } else {
-                    LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
-                    preparedAttrs.add(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");
-                }
-
-                task.setConnObjectKey(realm.getName());
-
-                task.setAttributes(preparedAttrs);
+                Pair<String, Set<Attribute>> preparedAttrs = mappingManager.prepareAttrs(realm, orgUnit);
+                task.setConnObjectKey(preparedAttrs.getKey());
+                task.setAttributes(preparedAttrs.getValue());
 
                 tasks.add(task);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index af8466c..1e93b92 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -178,7 +178,6 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
         }
 
         AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
         anyTO.getResources().add(profile.getTask().getResource().getKey());
 
         ProvisioningReport result = new ProvisioningReport();
@@ -324,9 +323,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                 result.setName(getName(before));
             }
 
-            Result resultStatus;
-            Object output;
             if (!profile.isDryRun()) {
+                Result resultStatus;
+                Object output;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -395,16 +395,13 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to update {}", anys);
+        LOG.debug("About to deprovision {}", anys);
 
-        final List<ProvisioningReport> updResults = new ArrayList<>();
+        final List<ProvisioningReport> results = new ArrayList<>();
 
         for (String key : anys) {
             LOG.debug("About to unassign resource {}", key);
 
-            Object output;
-            Result resultStatus;
-
             ProvisioningReport result = new ProvisioningReport();
             result.setOperation(ResourceOperation.DELETE);
             result.setAnyType(provision.getAnyType().getKey());
@@ -419,6 +416,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
 
             if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -487,10 +487,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                         ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
                         : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
             }
-            updResults.add(result);
+            results.add(result);
         }
 
-        return updResults;
+        return results;
     }
 
     protected List<ProvisioningReport> link(
@@ -510,14 +510,11 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
 
         LOG.debug("About to update {}", anys);
 
-        final List<ProvisioningReport> updResults = new ArrayList<>();
+        final List<ProvisioningReport> results = new ArrayList<>();
 
         for (String key : anys) {
             LOG.debug("About to unassign resource {}", key);
 
-            Object output;
-            Result resultStatus;
-
             ProvisioningReport result = new ProvisioningReport();
             result.setOperation(ResourceOperation.NONE);
             result.setAnyType(provision.getAnyType().getKey());
@@ -532,6 +529,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
 
             if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -585,10 +585,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                         ? MatchingRule.toEventName(MatchingRule.UNLINK)
                         : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
             }
-            updResults.add(result);
+            results.add(result);
         }
 
-        return updResults;
+        return results;
     }
 
     protected List<ProvisioningReport> delete(
@@ -605,7 +605,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
 
         LOG.debug("About to delete {}", anys);
 
-        List<ProvisioningReport> delResults = new ArrayList<>();
+        List<ProvisioningReport> results = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
         for (String key : anys) {
@@ -648,7 +648,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                     finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
                 }
 
-                delResults.add(result);
+                results.add(result);
             } catch (NotFoundException e) {
                 LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
             } catch (DelegatedAdministrationException e) {
@@ -658,7 +658,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
         }
 
-        return delResults;
+        return results;
     }
 
     protected ProvisioningReport ignore(

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
index cd2aaf3..d5b2093 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
@@ -23,7 +23,6 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.PasswordPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -76,10 +75,10 @@ public class DBPasswordPullActions extends DefaultPullActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         if (anyPatch instanceof UserPatch) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
index a75ff8b..9344835 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.java.pushpull;
 
 import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
@@ -38,10 +37,10 @@ public abstract class DefaultPullActions implements PullActions {
     }
 
     @Override
-    public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+    public <P extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final P anyMod) throws JobExecutionException {
 
         return delta;

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
index 967b27c..f11a20e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.java.pushpull;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.PasswordPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -70,10 +69,10 @@ public class LDAPPasswordPullActions extends DefaultPullActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         if (anyPatch instanceof UserPatch) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
index 33a9634..81bfd70 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
@@ -27,11 +27,11 @@ import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
 
@@ -47,7 +47,7 @@ public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
     @Override
     public SearchCond getSearchCond(final ConnectorObject connObj) {
         Map<String, MappingItem> mappingItems = new HashMap<>();
-        for (MappingItem item : MappingUtils.getPullMappingItems(provision)) {
+        for (MappingItem item : MappingUtils.getPullItems(provision)) {
             mappingItems.put(item.getIntAttrName(), item);
         }
 
@@ -65,7 +65,7 @@ public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
             }
 
             List<Object> values = attr.getValue();
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mappingItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mappingItem)) {
                 values = transformer.beforePull(mappingItem, null, values);
             }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index fa7807e..3520db0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -151,10 +151,10 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
         // First OrgUnits...
         if (pullTask.getResource().getOrgUnit() != null) {
             OrgUnit orgUnit = pullTask.getResource().getOrgUnit();
-            OperationOptions options = MappingUtils.buildOperationOptions(orgUnit);
+            OperationOptions options = MappingUtils.buildOperationOptions(
+                    MappingUtils.getPullItems(orgUnit).iterator());
 
-            SyncopePullResultHandler rhandler =
-                    (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
+            SyncopePullResultHandler rhandler = (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
                     createBean(RealmPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
             rhandler.setProfile(profile);
             rhandler.setPullExecutor(this);
@@ -181,8 +181,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
                     case FILTERED_RECONCILIATION:
                         ReconciliationFilterBuilder filterBuilder =
                                 (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
-                                createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
-                                        AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+                                        createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
+                                                AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
                         connector.filteredReconciliation(orgUnit.getObjectClass(),
                                 filterBuilder,
                                 rhandler,
@@ -265,8 +265,9 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
                         case FILTERED_RECONCILIATION:
                             ReconciliationFilterBuilder filterBuilder =
                                     (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
-                                    createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
-                                            AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+                                            createBean(
+                                                    Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
+                                                    AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
                             connector.filteredReconciliation(provision.getObjectClass(),
                                     filterBuilder,
                                     handler,

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
index e73517c..819c5f3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.pushpull;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.policy.PullPolicySpec;
@@ -31,6 +32,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -38,17 +40,19 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -62,7 +66,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Transactional(readOnly = true)
 @Component
@@ -101,6 +107,9 @@ public class PullUtils {
     private AnySearchDAO searchDAO;
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
@@ -130,7 +139,7 @@ public class PullUtils {
             public boolean handle(final ConnectorObject obj) {
                 return found.add(obj);
             }
-        }, MappingUtils.buildOperationOptions(MappingUtils.getPullMappingItems(provision).iterator()));
+        }, MappingUtils.buildOperationOptions(MappingUtils.getPullItems(provision).iterator()));
 
         if (found.isEmpty()) {
             LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
@@ -171,12 +180,10 @@ public class PullUtils {
     private List<String> findByConnObjectKeyItem(
             final String uid, final Provision provision, final AnyUtils anyUtils) {
 
-        List<String> result = new ArrayList<>();
-
         MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
 
         String transfUid = uid;
-        for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(connObjectKeyItem)) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
             List<Object> output = transformer.beforePull(
                     connObjectKeyItem,
                     null,
@@ -186,6 +193,8 @@ public class PullUtils {
             }
         }
 
+        List<String> result = new ArrayList<>();
+
         IntAttrName intAttrName = intAttrNameParser.parse(
                 connObjectKeyItem.getIntAttrName(),
                 provision.getAnyType().getKind());
@@ -323,6 +332,52 @@ public class PullUtils {
         }
     }
 
+    public List<String> findExisting(
+            final String uid,
+            final ConnectorObject connObj,
+            final OrgUnit orgUnit) {
+
+        OrgUnitItem connObjectKeyItem = orgUnit.getConnObjectKeyItem();
+
+        String transfUid = uid;
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
+            List<Object> output = transformer.beforePull(
+                    connObjectKeyItem,
+                    null,
+                    Collections.<Object>singletonList(transfUid));
+            if (output != null && !output.isEmpty()) {
+                transfUid = output.get(0).toString();
+            }
+        }
+
+        List<String> result = new ArrayList<>();
+
+        Realm realm;
+        switch (connObjectKeyItem.getIntAttrName()) {
+            case "key":
+                realm = realmDAO.find(transfUid);
+                if (realm != null) {
+                    result.add(realm.getKey());
+                }
+                break;
+
+            case "name":
+                CollectionUtils.collect(realmDAO.findByName(transfUid), EntityUtils.keyTransformer(), result);
+                break;
+
+            case "fullpath":
+                realm = realmDAO.findByFullPath(transfUid);
+                if (realm != null) {
+                    result.add(realm.getKey());
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
     public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
         Boolean enabled = null;
         if (task.isSyncStatus()) {


[11/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
index 37abe22..e13d6bb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
@@ -37,6 +37,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -52,7 +53,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
-public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
+public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> {
 
     private static final long serialVersionUID = 3739399543837732640L;
 
@@ -76,13 +77,18 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
                 }
             }, currentlyAdded);
 
-            return ListUtils.select(new AnyTypeRestClient().list(), new Predicate<String>() {
+            List<String> result = ListUtils.select(new AnyTypeRestClient().list(), new Predicate<String>() {
 
                 @Override
                 public boolean evaluate(final String key) {
                     return !currentlyAdded.contains(key);
                 }
             });
+            if (resourceTO.getOrgUnit() == null) {
+                result.add(0, SyncopeConstants.REALM_ANYTYPE);
+            }
+
+            return result;
         }
     };
 
@@ -93,7 +99,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = -1657800545799468278L;
 
-        ObjectType(final ProvisionTO item) {
+        ObjectType(final ResourceProvision item) {
             super(new ResourceModel("type.title", StringUtils.EMPTY),
                     new ResourceModel("type.summary", StringUtils.EMPTY), new Model<>(item));
 
@@ -135,14 +141,23 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
     /**
      * AuxClasses definition step.
      */
-    private static final class AuxClasses extends WizardStep {
+    private static final class AuxClasses extends WizardStep implements WizardModel.ICondition {
 
         private static final long serialVersionUID = 5315236191866427500L;
 
-        AuxClasses(final ProvisionTO item) {
+        private final ResourceProvision provision;
+
+        AuxClasses(final ResourceProvision item) {
+            this.provision = item;
+
             setTitleModel(new ResourceModel("auxClasses.title"));
             setSummaryModel(new StringResourceModel("auxClasses.summary", this, new Model<>(item)));
-            add(new ProvisionAuxClassesPanel("auxClasses", item));
+            add(new ProvisionAuxClassesPanel("auxClasses", item.getProvisionTO()));
+        }
+
+        @Override
+        public boolean evaluate() {
+            return provision.getProvisionTO() != null;
         }
     }
 
@@ -153,7 +168,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = 3454904947720856253L;
 
-        Mapping(final ProvisionTO item) {
+        Mapping(final ResourceProvision item) {
             setTitleModel(Model.of("Mapping"));
             setSummaryModel(Model.of(StringUtils.EMPTY));
         }
@@ -166,7 +181,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = 2359955465172450478L;
 
-        ConnObjectLink(final ProvisionTO item) {
+        ConnObjectLink(final ResourceProvision item) {
             super(new ResourceModel("link.title", StringUtils.EMPTY),
                     new ResourceModel("link.summary", StringUtils.EMPTY));
 
@@ -175,7 +190,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
             add(connObjectLinkContainer);
 
             boolean connObjectLinkEnabled = false;
-            if (StringUtils.isNotBlank(item.getMapping().getConnObjectLink())) {
+            if (StringUtils.isNotBlank(item.getConnObjectLink())) {
                 connObjectLinkEnabled = true;
             }
 
@@ -191,8 +206,9 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
             final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel(
                     "connObjectLink",
                     new ResourceModel("connObjectLink", "connObjectLink").getObject(),
-                    new PropertyModel<String>(item.getMapping(), "connObjectLink"),
+                    new PropertyModel<String>(item, "connObjectLink"),
                     false);
+            connObjectLink.enableJexlHelp();
             connObjectLink.setEnabled(connObjectLinkEnabled);
             connObjectLinkContainer.add(connObjectLink);
 
@@ -218,28 +234,27 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
      * @param pageRef Caller page reference.
      */
     public ProvisionWizardBuilder(final ResourceTO resurceTO, final PageReference pageRef) {
-        super(new ProvisionTO(), pageRef);
+        super(new ResourceProvision(), pageRef);
         this.resourceTO = resurceTO;
     }
 
     @Override
-    protected WizardModel buildModelSteps(final ProvisionTO modelObject, final WizardModel wizardModel) {
+    protected WizardModel buildModelSteps(final ResourceProvision modelObject, final WizardModel wizardModel) {
         wizardModel.add(new ObjectType(modelObject));
         wizardModel.add(new AuxClasses(modelObject));
 
         Mapping mapping = new Mapping(modelObject);
         mapping.setOutputMarkupId(true);
 
-        MappingItemTransformersTogglePanel mapItemTransformers =
-                new MappingItemTransformersTogglePanel(mapping, pageRef);
-        addOuterObject(mapItemTransformers);
+        ItemTransformersTogglePanel itemTransformers = new ItemTransformersTogglePanel(mapping, pageRef);
+        addOuterObject(itemTransformers);
         JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
         addOuterObject(jexlTransformers);
-        if (modelObject.getMapping() == null) {
-            modelObject.setMapping(new MappingTO());
+        if (modelObject.getProvisionTO() != null && modelObject.getProvisionTO().getMapping() == null) {
+            modelObject.getProvisionTO().setMapping(new MappingTO());
         }
         mapping.add(new ResourceMappingPanel(
-                "mapping", resourceTO, modelObject, mapItemTransformers, jexlTransformers));
+                "mapping", resourceTO, modelObject, itemTransformers, jexlTransformers));
 
         wizardModel.add(mapping);
 
@@ -248,28 +263,41 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
     }
 
     @Override
-    protected Serializable onApplyInternal(final ProvisionTO modelObject) {
-        final List<ProvisionTO> provisions;
-        if (modelObject.getKey() == null) {
-            provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+    protected Serializable onApplyInternal(final ResourceProvision modelObject) {
+        if (modelObject.getOrgUnitTO() != null) {
+            this.resourceTO.setOrgUnit(modelObject.getOrgUnitTO());
+
+            this.resourceTO.getOrgUnit().getItems().clear();
+            this.resourceTO.getOrgUnit().getItems().addAll(modelObject.getItems());
+        } else if (modelObject.getProvisionTO() != null) {
+            final List<ProvisionTO> provisions;
+            if (modelObject.getKey() == null) {
+                provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+
+                    @Override
+                    public boolean evaluate(final ProvisionTO object) {
+                        return !modelObject.getAnyType().equals(object.getAnyType());
+                    }
+                });
+            } else {
+                provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
 
-                @Override
-                public boolean evaluate(final ProvisionTO object) {
-                    return !modelObject.getAnyType().equals(object.getAnyType());
-                }
-            });
-        } else {
-            provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+                    @Override
+                    public boolean evaluate(final ProvisionTO object) {
+                        return !modelObject.getKey().equals(object.getKey());
+                    }
+                });
+            }
 
-                @Override
-                public boolean evaluate(final ProvisionTO object) {
-                    return !modelObject.getKey().equals(object.getKey());
-                }
-            });
+            ProvisionTO provisionTO = modelObject.getProvisionTO();
+            provisionTO.getMapping().getItems().clear();
+            provisionTO.getMapping().getItems().addAll(modelObject.getItems());
+            provisions.add(provisionTO);
+
+            this.resourceTO.getProvisions().clear();
+            this.resourceTO.getProvisions().addAll(provisions);
         }
-        provisions.add(modelObject);
-        this.resourceTO.getProvisions().clear();
-        this.resourceTO.getProvisions().addAll(provisions);
+
         return modelObject;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
index 93988e4..853873e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
@@ -26,10 +26,10 @@ import java.util.Set;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AbstractMappingPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -47,7 +47,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
     /**
      * External resource provisioning configuration instance to be updated.
      */
-    private final ProvisionTO provisionTO;
+    private final ResourceProvision provision;
 
     private final LoadableDetachableModel<List<String>> extAttrNames;
 
@@ -56,28 +56,28 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
      *
      * @param id panel id
      * @param resourceTO external resource to be updated
-     * @param provisionTO external resource provisioning configuration instance
-     * @param mapItemTransformers mapping item transformers toggle panel
+     * @param provision external resource provisioning configuration instance
+     * @param itemTransformers mapping item transformers toggle panel
      * @param jexlTransformers JEXL transformers toggle panel
      */
     public ResourceMappingPanel(
             final String id,
             final ResourceTO resourceTO,
-            final ProvisionTO provisionTO,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ResourceProvision provision,
+            final ItemTransformersTogglePanel itemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
         super(id,
-                mapItemTransformers,
+                itemTransformers,
                 jexlTransformers,
-                new ListModel<MappingItemTO>(provisionTO.getMapping().getItems()),
+                new ListModel<ItemTO>(provision.getItems()),
                 resourceTO.getConnector() != null,
                 false,
                 MappingPurpose.BOTH);
 
         setOutputMarkupId(true);
 
-        this.provisionTO = provisionTO;
+        this.provision = provision;
 
         extAttrNames = new LoadableDetachableModel<List<String>>() {
 
@@ -86,7 +86,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
             @Override
             protected List<String> load() {
                 return new ConnectorRestClient().getExtAttrNames(
-                        provisionTO.getObjectClass(),
+                        provision.getObjectClass(),
                         resourceTO.getConnector(),
                         resourceTO.getConfOverride());
             }
@@ -95,7 +95,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
 
     @Override
     protected boolean hidePassword() {
-        return !AnyTypeKind.USER.name().equals(provisionTO.getAnyType());
+        return !AnyTypeKind.USER.name().equals(provision.getAnyType());
     }
 
     @Override
@@ -106,7 +106,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
     @Override
     protected void onBeforeRender() {
         super.onBeforeRender();
-        passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provisionTO.getAnyType()));
+        passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provision.getAnyType()));
     }
 
     @Override
@@ -114,33 +114,38 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
         toBeUpdated.setRequired(true);
         toBeUpdated.setEnabled(true);
 
-        AnyTypeTO anyTypeTO = anyTypeRestClient.read(provisionTO.getAnyType());
-
-        List<AnyTypeClassTO> anyTypeClassTOs = new ArrayList<>();
-        anyTypeClassTOs.addAll(anyTypeClassRestClient.list(anyTypeTO.getClasses()));
-        for (String auxClass : provisionTO.getAuxClasses()) {
-            anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass));
-        }
-
         Set<String> choices = new HashSet<>();
+        if (SyncopeConstants.REALM_ANYTYPE.equals(provision.getAnyType())) {
+            choices.add("key");
+            choices.add("name");
+            choices.add("fullpath");
+        } else {
+            AnyTypeTO anyTypeTO = anyTypeRestClient.read(provision.getAnyType());
+
+            List<AnyTypeClassTO> anyTypeClassTOs = new ArrayList<>();
+            anyTypeClassTOs.addAll(anyTypeClassRestClient.list(anyTypeTO.getClasses()));
+            for (String auxClass : provision.getAuxClasses()) {
+                anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass));
+            }
 
-        switch (provisionTO.getAnyType()) {
-            case "USER":
-                choices.addAll(USER_FIELD_NAMES);
-                break;
+            switch (provision.getAnyType()) {
+                case "USER":
+                    choices.addAll(USER_FIELD_NAMES);
+                    break;
 
-            case "GROUP":
-                choices.addAll(GROUP_FIELD_NAMES);
-                break;
+                case "GROUP":
+                    choices.addAll(GROUP_FIELD_NAMES);
+                    break;
 
-            default:
-                choices.addAll(ANY_OBJECT_FIELD_NAMES);
-        }
+                default:
+                    choices.addAll(ANY_OBJECT_FIELD_NAMES);
+            }
 
-        for (AnyTypeClassTO anyTypeClassTO : anyTypeClassTOs) {
-            choices.addAll(anyTypeClassTO.getPlainSchemas());
-            choices.addAll(anyTypeClassTO.getDerSchemas());
-            choices.addAll(anyTypeClassTO.getVirSchemas());
+            for (AnyTypeClassTO anyTypeClassTO : anyTypeClassTOs) {
+                choices.addAll(anyTypeClassTO.getPlainSchemas());
+                choices.addAll(anyTypeClassTO.getDerSchemas());
+                choices.addAll(anyTypeClassTO.getVirSchemas());
+            }
         }
 
         final List<String> names = new ArrayList<>(choices);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
new file mode 100644
index 0000000..796fb76
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wizards.resources;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.OrgUnitTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+
+public class ResourceProvision implements Serializable {
+
+    private static final long serialVersionUID = 1103991919577739952L;
+
+    private ProvisionTO provisionTO;
+
+    private OrgUnitTO orgUnitTO;
+
+    private List<ItemTO> items;
+
+    public ResourceProvision() {
+        this.items = new ArrayList<>();
+    }
+
+    public ResourceProvision(final ProvisionTO provisionTO) {
+        setProvisionTO(provisionTO);
+    }
+
+    public ResourceProvision(final OrgUnitTO orgUnitTO) {
+        setOrgUnitTO(orgUnitTO);
+    }
+
+    public ProvisionTO getProvisionTO() {
+        return provisionTO;
+    }
+
+    public final void setProvisionTO(final ProvisionTO provisionTO) {
+        this.provisionTO = provisionTO;
+        this.orgUnitTO = null;
+
+        if (this.items == null) {
+            this.items = new ArrayList<>();
+        } else {
+            this.items.clear();
+        }
+        if (provisionTO.getMapping() != null) {
+            this.items.addAll(provisionTO.getMapping().getItems());
+        }
+    }
+
+    public OrgUnitTO getOrgUnitTO() {
+        return orgUnitTO;
+    }
+
+    public final void setOrgUnitTO(final OrgUnitTO orgUnitTO) {
+        this.orgUnitTO = orgUnitTO;
+        this.provisionTO = null;
+
+        if (this.items == null) {
+            this.items = new ArrayList<>();
+        } else {
+            this.items.clear();
+        }
+        this.items.addAll(orgUnitTO.getItems());
+    }
+
+    public String getKey() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getKey()
+                : provisionTO.getKey();
+    }
+
+    public String getAnyType() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : SyncopeConstants.REALM_ANYTYPE : provisionTO.getAnyType();
+    }
+
+    public void setAnyType(final String anyType) {
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyType)) {
+            setOrgUnitTO(new OrgUnitTO());
+        } else {
+            setProvisionTO(new ProvisionTO());
+            getProvisionTO().setAnyType(anyType);
+            getProvisionTO().setMapping(new MappingTO());
+        }
+    }
+
+    public String getObjectClass() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getObjectClass() : provisionTO.getObjectClass();
+    }
+
+    public void setObjectClass(final String objectClass) {
+        if (provisionTO == null) {
+            orgUnitTO.setObjectClass(objectClass);
+        } else {
+            provisionTO.setObjectClass(objectClass);
+        }
+    }
+
+    public List<String> getAuxClasses() {
+        return provisionTO == null ? Collections.<String>emptyList() : provisionTO.getAuxClasses();
+    }
+
+    public String getConnObjectLink() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getConnObjectLink()
+                : provisionTO.getMapping().getConnObjectLink();
+    }
+
+    public void setConnObjectLink(final String connObjectLink) {
+        if (provisionTO == null) {
+            orgUnitTO.setConnObjectLink(connObjectLink);
+        } else {
+            provisionTO.getMapping().setConnObjectLink(connObjectLink);
+        }
+    }
+
+    public List<ItemTO> getItems() {
+        return items;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
index 33e254a..26ce5d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
@@ -20,14 +20,12 @@ package org.apache.syncope.client.console.wizards.resources;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
@@ -36,45 +34,33 @@ import org.apache.syncope.client.console.panels.AbstractModalPanel;
 import org.apache.syncope.client.console.panels.ListViewPanel;
 import org.apache.syncope.client.console.panels.ListViewPanel.ListViewReload;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
-import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
 public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
 
     private static final long serialVersionUID = -7982691107029848579L;
 
-    private final ConnectorRestClient connectorRestClient = new ConnectorRestClient();
-
     private final ResourceRestClient resourceRestClient = new ResourceRestClient();
 
     private final ResourceTO resourceTO;
 
-    private Model<OrgUnitTO> baseModel;
-
-    private final WebMarkupContainer aboutRealmProvison;
+    private final List<ResourceProvision> provisions;
 
     public ResourceProvisionPanel(
             final BaseModal<Serializable> modal,
@@ -84,108 +70,25 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
         super(modal, pageRef);
         this.resourceTO = resourceTO;
 
-        baseModel = Model.of(resourceTO.getOrgUnit() == null ? new OrgUnitTO() : resourceTO.getOrgUnit());
-
         setOutputMarkupId(true);
 
-        // ----------------------------------------------------------------------
-        // Realms provisioning
-        // ----------------------------------------------------------------------
-        aboutRealmProvison = new WebMarkupContainer("aboutRealmProvison");
-        aboutRealmProvison.setOutputMarkupPlaceholderTag(true);
-        add(aboutRealmProvison);
-
-        boolean realmProvisionEnabled = resourceTO.getOrgUnit() != null;
-
-        final AjaxCheckBoxPanel enableRealmsProvision = new AjaxCheckBoxPanel(
-                "enableRealmsProvision",
-                "enableRealmsProvision",
-                Model.of(realmProvisionEnabled),
-                false);
-        aboutRealmProvison.add(enableRealmsProvision);
-        enableRealmsProvision.setIndex(1).setTitle(getString("enableRealmsProvision.title"));
-
-        final WebMarkupContainer realmsProvisionContainer = new WebMarkupContainer("realmsProvisionContainer");
-        realmsProvisionContainer.setOutputMarkupPlaceholderTag(true);
-        realmsProvisionContainer.setEnabled(realmProvisionEnabled).setVisible(realmProvisionEnabled);
-        aboutRealmProvison.add(realmsProvisionContainer);
-
-        final AjaxTextFieldPanel objectClass = new AjaxTextFieldPanel(
-                "objectClass",
-                getString("objectClass"),
-                new PropertyModel<String>(baseModel.getObject(), "objectClass"),
-                false);
-        realmsProvisionContainer.add(objectClass.addRequiredLabel());
-
-        final AjaxTextFieldPanel extAttrName = new AjaxTextFieldPanel(
-                "extAttrName",
-                getString("extAttrName"),
-                new PropertyModel<String>(baseModel.getObject(), "extAttrName"),
-                false);
-        if (resourceTO.getOrgUnit() != null) {
-            extAttrName.setChoices(connectorRestClient.getExtAttrNames(
-                    resourceTO.getOrgUnit().getObjectClass(),
-                    resourceTO.getConnector(),
-                    resourceTO.getConfOverride()));
-        }
-        realmsProvisionContainer.add(extAttrName.addRequiredLabel());
-
-        objectClass.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                extAttrName.setChoices(connectorRestClient.getExtAttrNames(
-                        objectClass.getModelObject(),
-                        resourceTO.getConnector(),
-                        resourceTO.getConfOverride()));
-                target.focusComponent(extAttrName);
-            }
-        });
-
-        final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel(
-                "connObjectLink",
-                new ResourceModel("connObjectLink", "connObjectLink").getObject(),
-                new PropertyModel<String>(baseModel.getObject(), "connObjectLink"),
-                false);
-        realmsProvisionContainer.add(connObjectLink.addRequiredLabel());
-
-        enableRealmsProvision.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                boolean realmProvisionEnabled = enableRealmsProvision.getModelObject();
-                realmsProvisionContainer.setEnabled(realmProvisionEnabled).setVisible(realmProvisionEnabled);
-                target.add(realmsProvisionContainer);
-
-                if (realmProvisionEnabled) {
-                    resourceTO.setOrgUnit(baseModel.getObject());
-                } else {
-                    resourceTO.setOrgUnit(null);
-                }
-
-            }
-        });
-        // ----------------------------------------------------------------------
-
         final ProvisionWizardBuilder wizard = new ProvisionWizardBuilder(resourceTO, pageRef);
 
-        final ListViewPanel.Builder<ProvisionTO> builder = new ListViewPanel.Builder<ProvisionTO>(
-                ProvisionTO.class, pageRef) {
+        final ListViewPanel.Builder<ResourceProvision> builder = new ListViewPanel.Builder<ResourceProvision>(
+                ResourceProvision.class, pageRef) {
 
             private static final long serialVersionUID = 4907732721283972943L;
 
             @Override
-            protected ProvisionTO getActualItem(final ProvisionTO item, final List<ProvisionTO> list) {
+            protected ResourceProvision getActualItem(
+                    final ResourceProvision item, final List<ResourceProvision> list) {
+
                 return item == null
                         ? null
-                        : IteratorUtils.find(list.iterator(), new Predicate<ProvisionTO>() {
+                        : IteratorUtils.find(list.iterator(), new Predicate<ResourceProvision>() {
 
                             @Override
-                            public boolean evaluate(final ProvisionTO in) {
+                            public boolean evaluate(final ResourceProvision in) {
                                 return ((item.getKey() == null && in.getKey() == null)
                                         || (in.getKey() != null && in.getKey().equals(item.getKey())))
                                         && ((item.getAnyType() == null && in.getAnyType() == null)
@@ -202,45 +105,46 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
 
             @Override
             protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
-                ResourceProvisionPanel.this.aboutRealmProvison.setVisible(true);
-                target.add(ResourceProvisionPanel.this.aboutRealmProvison);
-
                 // change modal footer visibility
                 send(ResourceProvisionPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
             }
 
             @Override
             protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
-                ResourceProvisionPanel.this.aboutRealmProvison.setVisible(true);
-                target.add(ResourceProvisionPanel.this.aboutRealmProvison);
-
                 // keep list ordered - SYNCOPE-1154
-                sortProvisionList();
+                sortProvisions();
 
                 // change modal footer visibility
                 send(ResourceProvisionPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
             }
         };
 
+        provisions = new ArrayList<>();
+        if (resourceTO.getOrgUnit() != null) {
+            provisions.add(new ResourceProvision(resourceTO.getOrgUnit()));
+        }
+        for (ProvisionTO provision : resourceTO.getProvisions()) {
+            provisions.add(new ResourceProvision(provision));
+        }
         // keep list ordered - SYNCOPE-1154
-        sortProvisionList();
+        sortProvisions();
 
-        builder.setItems(resourceTO.getProvisions());
+        builder.setItems(provisions);
         builder.includes("anyType", "objectClass", "auxClasses");
         builder.setReuseItem(false);
 
-        builder.addAction(new ActionLink<ProvisionTO>() {
+        builder.addAction(new ActionLink<ResourceProvision>() {
 
             private static final long serialVersionUID = -3722207913631435504L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+            public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                 try {
                     send(ResourceProvisionPanel.this, Broadcast.DEPTH,
-                            new AjaxWizard.NewItemActionEvent<>(provisionTO, 2, target).setResourceModel(
+                            new AjaxWizard.NewItemActionEvent<>(provision, 2, target).setResourceModel(
                                     new StringResourceModel("inner.provision.mapping",
                                             ResourceProvisionPanel.this,
-                                            Model.of(provisionTO))));
+                                            Model.of(provision))));
                 } catch (SyncopeClientException e) {
                     LOG.error("While contacting resource", e);
                     SyncopeConsoleSession.get().error(
@@ -249,105 +153,97 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
                 }
             }
         }, ActionLink.ActionType.MAPPING, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -7780999687733432439L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                         try {
-                            resourceRestClient.setLatestSyncToken(resourceTO.getKey(), provisionTO.getAnyType());
+                            resourceRestClient.setLatestSyncToken(resourceTO.getKey(), provision.getAnyType());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                         } catch (Exception e) {
                             LOG.error("While setting latest sync token for {}/{}",
-                                    resourceTO.getKey(), provisionTO.getAnyType(), e);
+                                    resourceTO.getKey(), provision.getAnyType(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
                 }, ActionLink.ActionType.SET_LATEST_SYNC_TOKEN, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -7780999687733432439L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                         try {
-                            resourceRestClient.removeSyncToken(resourceTO.getKey(), provisionTO.getAnyType());
+                            resourceRestClient.removeSyncToken(resourceTO.getKey(), provision.getAnyType());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                         } catch (Exception e) {
                             LOG.error("While removing sync token for {}/{}",
-                                    resourceTO.getKey(), provisionTO.getAnyType(), e);
+                                    resourceTO.getKey(), provision.getAnyType(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
                 }, ActionLink.ActionType.REMOVE_SYNC_TOKEN, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
-
-                    private static final long serialVersionUID = -3722207913631435534L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                        final ProvisionTO clone = SerializationUtils.clone(provisionTO);
-                        clone.setKey(null);
-                        clone.setAnyType(null);
-                        clone.setObjectClass(null);
-                        send(ResourceProvisionPanel.this, Broadcast.DEPTH,
-                                new AjaxWizard.NewItemActionEvent<>(clone, target).setResourceModel(
-                                        new StringResourceModel("inner.provision.clone",
-                                                ResourceProvisionPanel.this,
-                                                Model.of(provisionTO))));
-                    }
-                }, ActionLink.ActionType.CLONE, StandardEntitlement.RESOURCE_CREATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -3722207913631435544L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                        resourceTO.getProvisions().remove(provisionTO);
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
+                        if (provision.getOrgUnitTO() != null) {
+                            resourceTO.setOrgUnit(null);
+                        } else if (provision.getProvisionTO() != null) {
+                            resourceTO.getProvisions().remove(provision.getProvisionTO());
+                        }
+                        provisions.remove(provision);
                         send(ResourceProvisionPanel.this, Broadcast.DEPTH, new ListViewReload<>(target));
                     }
-                }, ActionLink.ActionType.DELETE, StandardEntitlement.RESOURCE_DELETE);
+                }, ActionLink.ActionType.DELETE, StandardEntitlement.RESOURCE_UPDATE);
 
         builder.addNewItemPanelBuilder(wizard);
 
-        final WizardMgtPanel<ProvisionTO> list = builder.build("provision");
+        final WizardMgtPanel<ResourceProvision> list = builder.build("provision");
         add(list);
     }
 
+    private void checkConnObjectKeyCount(final String anyType, final List<ItemTO> items) {
+        long connObjectKeyCount = IterableUtils.countMatches(items, new Predicate<ItemTO>() {
+
+            @Override
+            public boolean evaluate(final ItemTO item) {
+                return item.isConnObjectKey();
+            }
+        });
+
+        if (connObjectKeyCount != 1) {
+            throw new IllegalArgumentException(anyType + ": "
+                    + new StringResourceModel("connObjectKeyValidation", ResourceProvisionPanel.this).getString());
+        }
+    }
+
     @Override
     public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
         try {
-            final Collection<ProvisionTO> provisions = new ArrayList<>(resourceTO.getProvisions());
+            if (resourceTO.getOrgUnit() != null) {
+                checkConnObjectKeyCount(SyncopeConstants.REALM_ANYTYPE, resourceTO.getOrgUnit().getItems());
+            }
 
-            for (ProvisionTO provision : provisions) {
+            for (ProvisionTO provision : new ArrayList<>(resourceTO.getProvisions())) {
                 if (provision != null) {
                     if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) {
                         resourceTO.getProvisions().remove(provision);
                     } else {
-                        long connObjectKeyCount = IterableUtils.countMatches(
-                                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                            @Override
-                            public boolean evaluate(final MappingItemTO item) {
-                                return item.isConnObjectKey();
-                            }
-                        });
-
-                        if (connObjectKeyCount != 1) {
-                            throw new IllegalArgumentException(provision.getAnyType() + ": "
-                                    + new StringResourceModel("connObjectKeyValidation", ResourceProvisionPanel.this).
-                                            getString());
-                        }
+                        checkConnObjectKeyCount(provision.getAnyType(), provision.getMapping().getItems());
                     }
                 }
             }
 
-            new ResourceRestClient().update(resourceTO);
+            resourceRestClient.update(resourceTO);
             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
             modal.close(target);
         } catch (Exception e) {
@@ -358,24 +254,13 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
 
-    private void sortProvisionList() {
-        Collections.sort(resourceTO.getProvisions(), new Comparator<ProvisionTO>() {
+    private void sortProvisions() {
+        Collections.sort(provisions, new Comparator<ResourceProvision>() {
 
             @Override
-            public int compare(final ProvisionTO o1, final ProvisionTO o2) {
+            public int compare(final ResourceProvision o1, final ResourceProvision o2) {
                 return new AnyTypeRestClient.AnyTypeKeyComparator().compare(o1.getAnyType(), o2.getAnyType());
             }
         });
     }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent) {
-            aboutRealmProvison.setVisible(false);
-            final AjaxRequestTarget target = ((AjaxWizard.NewItemEvent) event.getPayload()).getTarget();
-            target.add(aboutRealmProvison);
-        }
-
-        super.onEvent(event);
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 5b81fc2..8763e9a 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -575,7 +575,7 @@ div#startAt {
   z-index: 6000 !important;
 }
 
-div#mappingItemTransformersTogglePanel {
+div#itemTransformersTogglePanel {
   min-width: 1000px;
 }
 
@@ -994,12 +994,12 @@ div.transformersContainer #body {
   display: block;
 }
 
-div.mappingItemTransformersContainer #body select {
+div.itemTransformersContainer #body select {
   border: 1px solid #ccc !important;
   background: rgba(240, 240, 240, 0.95) !important
 }
 
-div.mappingItemTransformersContainer #body a {
+div.itemTransformersContainer #body a {
   color: #ccc !important;
   cursor: pointer !important;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
new file mode 100644
index 0000000..5c2d15d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} selected transformer(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
new file mode 100644
index 0000000..8e23aef
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} transformer selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
new file mode 100644
index 0000000..0fd94d7
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} JEXL transforming expression(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
new file mode 100644
index 0000000..e79d679
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+alerts.view.all=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
+summary=\u0412\u044b\u0431\u0440\u0430\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432: ${number}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
deleted file mode 100644
index 5c2d15d..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} selected transformer(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
deleted file mode 100644
index 8e23aef..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} transformer selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
deleted file mode 100644
index 0fd94d7..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} JEXL transforming expression(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
deleted file mode 100644
index e79d679..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
+++ /dev/null
@@ -1,19 +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.
-#
-alerts.view.all=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
-summary=\u0412\u044b\u0431\u0440\u0430\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432: ${number}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
index 538d804..57339dd 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
@@ -57,7 +57,7 @@ under the License.
               </td>
               <td>
                 <div class="alert-widget dropdown tasks-menu">
-                  <span wicket:id="mappingItemTransformers">[Mapping Item Transformers]</span>
+                  <span wicket:id="itemTransformers">[Mapping Item Transformers]</span>
                 </div>
               </td>
               <td>

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
new file mode 100644
index 0000000..01ef653
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <div id="itemTransformersContainer" class="transformersContainer">
+      <form wicket:id="form">
+        <div id="body">
+          <span wicket:id="classes"/>
+        </div>
+        <div id="footer">
+          <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
+        </div>
+      </form>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
new file mode 100644
index 0000000..06d3702
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Finish
+palette.available=Available Mapping Item Transformers
+palette.selected=Selected Mapping Item Transformers

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
new file mode 100644
index 0000000..9e80b99
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Fine
+palette.available=Mapping Item Transformer Disponibili
+palette.selected=Mapping Item Transformer Selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
new file mode 100644
index 0000000..d5a72dc
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Finish
+palette.available=Available Mapping Item Transformers
+palette.selected=Mapping Item

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
new file mode 100644
index 0000000..5f823ee
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+finish=\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c
+palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
+palette.selected=\u041c\u0430\u043f\u043f\u0438\u043d\u0433 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
deleted file mode 100644
index 8983a41..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:extend>
-    <div id="mappingItemTransformersContainer" class="transformersContainer">
-      <form wicket:id="form">
-        <div id="body">
-          <span wicket:id="classes"/>
-        </div>
-        <div id="footer">
-          <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
-        </div>
-      </form>
-    </div>
-  </wicket:extend>
-</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
deleted file mode 100644
index 06d3702..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Finish
-palette.available=Available Mapping Item Transformers
-palette.selected=Selected Mapping Item Transformers

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
deleted file mode 100644
index 9e80b99..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Fine
-palette.available=Mapping Item Transformer Disponibili
-palette.selected=Mapping Item Transformer Selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
deleted file mode 100644
index d5a72dc..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Finish
-palette.available=Available Mapping Item Transformers
-palette.selected=Mapping Item

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
deleted file mode 100644
index 5f823ee..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
+++ /dev/null
@@ -1,20 +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.
-#
-finish=\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c
-palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
-palette.selected=\u041c\u0430\u043f\u043f\u0438\u043d\u0433 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
index de5c92f..ef243a8 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
@@ -18,14 +18,6 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div wicket:id="aboutRealmProvison" class="col-xs-12 panel-body">
-      <span wicket:id="enableRealmsProvision"/>
-      <div wicket:id="realmsProvisionContainer">
-        <span wicket:id="objectClass"/>
-        <span wicket:id="extAttrName"/>
-        <span wicket:id="connObjectLink"/>
-      </div>
-    </div>
     <span wicket:id="provision">[PROVISION]</span>
   </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
index a50917d..47bfff5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
@@ -18,13 +18,8 @@ anyType=Object Type
 objectClass= Object Class
 auxClasses=Auxiliary Classes
 
-extAttrName=External attribute
-
 connObjectKeyValidation=There must be exactly one Remote Key
 propagationMode=Propagation mode
-connObjectLink=Object Link
 enable=Enable
 inner.provision.mapping=${anyType} provision
 inner.provision.clone=Clone provision '${key}'
-enableRealmsProvision=Enable realm provisioning
-enableRealmsProvision.title=Enable the possibility to provision realms towards external resource

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
index 6e7dac6..da47b7f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
@@ -18,13 +18,8 @@ anyType=Tipo oggetto
 objectClass=Classe
 auxClasses=Classi Ausiliarie
 
-extAttrName=Attributo esterno
-
 connObjectKeyValidation=Deve essere definito esattamente una Chiave remota
 propagationMode=Modalit\u00e0 di propagazione
-connObjectLink=ID Remoto
 enable=Abilita
 inner.provision.mapping=Provision ${anyType}
 inner.provision.clone=Clona il provision '${key}'
-enableRealmsProvision=Abilita il provisioning dei realm
-enableRealmsProvision.title=Abilita la possibilit\u00e0 di effettuare il provisioning dei realm verso la risorsa esterna

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
index bdd9e92..9f49625 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
@@ -18,13 +18,8 @@ anyType=Object Type
 objectClass=Classe
 auxClasses=Classes Auxiliares
 
-extAttrName=Atributo Externo
-
 connObjectKeyValidation=Precisa ser exatamente um Remote Key
 propagationMode=Modo de propaga\u00e7\u00e3o
-connObjectLink=Remote ID
 enable=Habilitado
 inner.provision.mapping=${anyType} provision
 inner.provision.clone=Clone provision '${key}'
-enableRealmsProvision=Enable realm provisioning
-enableRealmsProvision.title=Enable the possibility to provision realms towards external resource

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
index b06c382..919bd00 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
@@ -18,13 +18,8 @@ anyType=\u0422\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
 objectClass=\u041a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
 auxClasses=\u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043b\u044e\u0447
 
-extAttrName=\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b
-
 connObjectKeyValidation=\u0422\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
 propagationMode=\u0420\u0435\u0436\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439
-connObjectLink=\u0421\u0432\u044f\u0437\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432
 enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
 inner.provision.mapping=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 ${anyType}
 inner.provision.clone=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 '${key}'
-enableRealmsProvision=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u0438
-enableRealmsProvision.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
index 0594db4..76495b7 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
@@ -81,7 +81,7 @@ public class PlatformInfo extends AbstractBaseBean {
 
     private final Set<String> passwordRules = new HashSet<>();
 
-    private final Set<String> mappingItemTransformers = new HashSet<>();
+    private final Set<String> itemTransformers = new HashSet<>();
 
     private final Set<String> taskJobs = new HashSet<>();
 
@@ -233,11 +233,11 @@ public class PlatformInfo extends AbstractBaseBean {
         return passwordRules;
     }
 
-    @XmlElementWrapper(name = "mappingItemTransformers")
-    @XmlElement(name = "mappingItemTransformer")
-    @JsonProperty("mappingItemTransformers")
-    public Set<String> getMappingItemTransformers() {
-        return mappingItemTransformers;
+    @XmlElementWrapper(name = "itemTransformers")
+    @XmlElement(name = "itemTransformer")
+    @JsonProperty("itemTransformers")
+    public Set<String> getItemTransformers() {
+        return itemTransformers;
     }
 
     @XmlElementWrapper(name = "taskJobs")


[02/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
index fc711ca..c4be4e2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
@@ -18,14 +18,10 @@
  */
 package org.apache.syncope.core.provisioning.java.pushpull;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -47,14 +43,13 @@ import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
-import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
-import org.identityconnectors.framework.common.objects.Attribute;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.quartz.JobExecutionException;
@@ -67,6 +62,12 @@ public class RealmPullResultHandlerImpl
         implements SyncopePullResultHandler {
 
     @Autowired
+    private PullUtils pullUtils;
+
+    @Autowired
+    private ConnObjectUtils connObjectUtils;
+
+    @Autowired
     private AnySearchDAO searchDAO;
 
     private SyncopePullExecutor executor;
@@ -125,24 +126,32 @@ public class RealmPullResultHandlerImpl
         }
     }
 
-    private ProvisioningReport assign(final SyncDelta delta, final String name) throws JobExecutionException {
+    private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
         if (!profile.getTask().isPerformCreate()) {
             LOG.debug("PullTask not configured for create");
-            return null;
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        RealmTO realmTO = new RealmTO();
-        realmTO.setName(name);
+        RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+        if (realmTO.getFullPath() == null) {
+            if (realmTO.getParent() == null) {
+                realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+            }
+
+            realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+        }
         realmTO.getResources().add(profile.getTask().getResource().getKey());
 
         ProvisioningReport result = new ProvisioningReport();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(REALM_TYPE);
         result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(profile.getTask().getDestinatioRealm().getFullPath() + "/" + name);
+        result.setName(realmTO.getFullPath());
 
         if (profile.isDryRun()) {
             result.setKey(null);
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
         } else {
             SyncDelta actionedDelta = delta;
             for (PullActions action : profile.getActions()) {
@@ -152,27 +161,36 @@ public class RealmPullResultHandlerImpl
             create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
         }
 
-        return result;
+        return Collections.singletonList(result);
     }
 
-    private ProvisioningReport provision(final SyncDelta delta, final String name) throws JobExecutionException {
+    private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
+            throws JobExecutionException {
+
         if (!profile.getTask().isPerformCreate()) {
             LOG.debug("PullTask not configured for create");
-            return null;
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        RealmTO realmTO = new RealmTO();
-        realmTO.setName(name);
-        realmTO.getResources().add(profile.getTask().getResource().getKey());
+        RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+        if (realmTO.getFullPath() == null) {
+            if (realmTO.getParent() == null) {
+                realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+            }
+
+            realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+        }
 
         ProvisioningReport result = new ProvisioningReport();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(REALM_TYPE);
         result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(profile.getTask().getDestinatioRealm().getFullPath() + "/" + name);
+        result.setName(realmTO.getFullPath());
 
         if (profile.isDryRun()) {
             result.setKey(null);
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
         } else {
             SyncDelta actionedDelta = delta;
             for (PullActions action : profile.getActions()) {
@@ -182,7 +200,7 @@ public class RealmPullResultHandlerImpl
             create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
         }
 
-        return result;
+        return Collections.singletonList(result);
     }
 
     private void throwIgnoreProvisionException(final SyncDelta delta, final Exception exception)
@@ -255,293 +273,378 @@ public class RealmPullResultHandlerImpl
         finalize(operation, resultStatus, null, output, delta);
     }
 
-    private ProvisioningReport update(final SyncDelta delta, final Realm realm, final String name)
+    private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to update {}", realm);
-
-        RealmTO before = binder.getRealmTO(realm, true);
-
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.UPDATE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        LOG.debug("About to update {}", keys);
 
-        Result resultStatus;
-        Object output;
-        if (!profile.isDryRun()) {
-            try {
-                before.setName(name);
+        List<ProvisioningReport> results = new ArrayList<>();
 
-                PropagationByResource propByRes = binder.update(realm, before);
-                Realm updated = realmDAO.save(realm);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to update {}", key);
 
-                List<PropagationTask> tasks = propagationManager.createTasks(updated, propByRes, null);
-                PropagationReporter propagationReporter = taskExecutor.execute(tasks, false);
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.UPDATE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-                output = updated;
-                resultStatus = Result.SUCCESS;
-                result.setName(updated.getFullPath());
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                LOG.debug("{} successfully updated", updated);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
+            if (!profile.isDryRun()) {
+                Result resultStatus;
+                Object output;
 
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
+                } else {
+                    try {
+                        for (PullActions action : profile.getActions()) {
+                            workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
+                        }
+
+                        PropagationByResource propByRes = binder.update(realm, before);
+                        realm = realmDAO.save(realm);
+                        RealmTO updated = binder.getRealmTO(realm, true);
+
+                        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+                        taskExecutor.execute(tasks, false);
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, updated, result);
+                        }
+
+                        output = updated;
+                        resultStatus = Result.SUCCESS;
+                        result.setName(updated.getFullPath());
+
+                        LOG.debug("{} successfully updated", updated);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
+                }
+                finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
             }
-            finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport deprovision(final SyncDelta delta, final Realm realm, final boolean unlink)
+    private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(unlink
+                    ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+                    : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to deprovision {}", realm);
+        LOG.debug("About to deprovision {}", keys);
 
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.DELETE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        final List<ProvisioningReport> results = new ArrayList<>();
 
-        RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to unassign resource {}", key);
 
-        Object output;
-        Result resultStatus;
-        if (!profile.isDryRun()) {
-            result.setName(realm.getFullPath());
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.DELETE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-            try {
-                if (unlink) {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeUnassign(profile, delta, before);
-                    }
-                } else {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeDeprovision(profile, delta, before);
-                    }
-                }
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                PropagationByResource propByRes = new PropagationByResource();
-                propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+            if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
 
-                if (unlink) {
-                    realm.getResources().remove(profile.getTask().getResource());
-                    output = binder.getRealmTO(realmDAO.save(realm), true);
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
                 } else {
-                    output = binder.getRealmTO(realm, true);
-                }
-
-                for (PullActions action : profile.getActions()) {
-                    action.after(profile, delta, RealmTO.class.cast(output), result);
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeUnassign(profile, workingDelta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeDeprovision(profile, workingDelta, before);
+                            }
+                        }
+
+                        PropagationByResource propByRes = new PropagationByResource();
+                        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+                        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+
+                        if (unlink) {
+                            realm.getResources().remove(profile.getTask().getResource());
+                            output = binder.getRealmTO(realmDAO.save(realm), true);
+                        } else {
+                            output = binder.getRealmTO(realm, true);
+                        }
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, RealmTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+
+                        LOG.debug("{} successfully updated", realm);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
                 }
-
-                resultStatus = Result.SUCCESS;
-
-                LOG.debug("{} successfully updated", realm);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
-
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                finalize(unlink
+                        ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+                        : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
             }
-
-            finalize(unlink
-                    ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
-                    : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport link(final SyncDelta delta, final Realm realm, final boolean unlink)
+    private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(unlink
+                    ? MatchingRule.toEventName(MatchingRule.UNLINK)
+                    : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to link {}", realm);
+        LOG.debug("About to link {}", keys);
 
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.NONE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        final List<ProvisioningReport> results = new ArrayList<>();
 
-        RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to unassign resource {}", key);
 
-        Object output;
-        Result resultStatus;
-        if (!profile.isDryRun()) {
-            result.setName(realm.getFullPath());
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.NONE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-            try {
-                if (unlink) {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeUnlink(profile, delta, before);
-                    }
-                } else {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeLink(profile, delta, before);
-                    }
-                }
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                if (unlink) {
-                    realm.getResources().remove(profile.getTask().getResource());
+            Object output;
+            Result resultStatus;
+            if (!profile.isDryRun()) {
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
                 } else {
-                    realm.add(profile.getTask().getResource());
-                }
-                output = update(delta, realm, realm.getName());
-
-                for (PullActions action : profile.getActions()) {
-                    action.after(profile, delta, RealmTO.class.cast(output), result);
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeUnlink(profile, workingDelta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeLink(profile, workingDelta, before);
+                            }
+                        }
+
+                        if (unlink) {
+                            realm.getResources().remove(profile.getTask().getResource());
+                        } else {
+                            realm.add(profile.getTask().getResource());
+                        }
+                        output = update(workingDelta, Collections.singletonList(key));
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, RealmTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+
+                        LOG.debug("{} successfully updated", realm);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
                 }
-
-                resultStatus = Result.SUCCESS;
-
-                LOG.debug("{} successfully updated", realm);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
-
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                finalize(unlink
+                        ? MatchingRule.toEventName(MatchingRule.UNLINK)
+                        : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
             }
-
-            finalize(unlink
-                    ? MatchingRule.toEventName(MatchingRule.UNLINK)
-                    : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport delete(final SyncDelta delta, final Realm realm)
+    private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformDelete()) {
             LOG.debug("PullTask not configured for delete");
-            return null;
+            finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to delete {}", realm);
+        LOG.debug("About to delete {}", keys);
 
-        SyncDelta workingDelta = delta;
-        Object output;
-        Result resultStatus = Result.FAILURE;
+        List<ProvisioningReport> results = new ArrayList<>();
 
-        ProvisioningReport result = new ProvisioningReport();
-
-        try {
-            RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            Object output;
+            Result resultStatus = Result.FAILURE;
 
-            result.setKey(realm.getKey());
-            result.setName(realm.getFullPath());
-            result.setOperation(ResourceOperation.DELETE);
-            result.setAnyType(REALM_TYPE);
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            ProvisioningReport result = new ProvisioningReport();
 
-            if (!profile.isDryRun()) {
-                for (PullActions action : profile.getActions()) {
-                    workingDelta = action.beforeDelete(profile, workingDelta, before);
+            try {
+                result.setKey(key);
+                result.setOperation(ResourceOperation.DELETE);
+                result.setAnyType(REALM_TYPE);
+                result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+                Realm realm = realmDAO.find(key);
+                RealmTO before = binder.getRealmTO(realm, true);
+                if (before == null) {
+                    result.setStatus(ProvisioningReport.Status.FAILURE);
+                    result.setMessage(String.format("Realm '%s' not found", key));
+                } else {
+                    result.setName(before.getFullPath());
                 }
 
-                try {
-                    if (!realmDAO.findChildren(realm).isEmpty()) {
-                        throw SyncopeClientException.build(ClientExceptionType.HasChildren);
-                    }
-
-                    Set<String> adminRealms = Collections.singleton(realm.getFullPath());
-                    AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
-                    keyCond.setSchema("key");
-                    SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
-                    int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
-                    int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
-                    int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
-
-                    if (users + groups + anyObjects > 0) {
-                        SyncopeClientException containedAnys = SyncopeClientException.build(
-                                ClientExceptionType.AssociatedAnys);
-                        containedAnys.getElements().add(users + " user(s)");
-                        containedAnys.getElements().add(groups + " group(s)");
-                        containedAnys.getElements().add(anyObjects + " anyObject(s)");
-                        throw containedAnys;
+                if (!profile.isDryRun()) {
+                    for (PullActions action : profile.getActions()) {
+                        workingDelta = action.beforeDelete(profile, workingDelta, before);
                     }
 
-                    PropagationByResource propByRes = new PropagationByResource();
-                    for (String resource : realm.getResourceKeys()) {
-                        propByRes.add(ResourceOperation.DELETE, resource);
+                    try {
+                        if (!realmDAO.findChildren(realm).isEmpty()) {
+                            throw SyncopeClientException.build(ClientExceptionType.HasChildren);
+                        }
+
+                        Set<String> adminRealms = Collections.singleton(realm.getFullPath());
+                        AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
+                        keyCond.setSchema("key");
+                        SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
+                        int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
+                        int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
+                        int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
+
+                        if (users + groups + anyObjects > 0) {
+                            SyncopeClientException containedAnys = SyncopeClientException.build(
+                                    ClientExceptionType.AssociatedAnys);
+                            containedAnys.getElements().add(users + " user(s)");
+                            containedAnys.getElements().add(groups + " group(s)");
+                            containedAnys.getElements().add(anyObjects + " anyObject(s)");
+                            throw containedAnys;
+                        }
+
+                        PropagationByResource propByRes = new PropagationByResource();
+                        for (String resource : realm.getResourceKeys()) {
+                            propByRes.add(ResourceOperation.DELETE, resource);
+                        }
+                        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+                        taskExecutor.execute(tasks, false);
+
+                        realmDAO.delete(realm);
+
+                        output = null;
+                        resultStatus = Result.SUCCESS;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, before, result);
+                        }
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not delete {}", realm, e);
+                        output = e;
                     }
-                    List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
-                    PropagationReporter propagationReporter = taskExecutor.execute(tasks, false);
-
-                    realmDAO.delete(realm);
 
-                    output = null;
-                    resultStatus = Result.SUCCESS;
-
-                    for (PullActions action : profile.getActions()) {
-                        action.after(profile, workingDelta, before, result);
-                    }
-                } catch (Exception e) {
-                    throwIgnoreProvisionException(delta, e);
-
-                    result.setStatus(ProvisioningReport.Status.FAILURE);
-                    result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                    LOG.error("Could not delete {}", realm, e);
-                    output = e;
+                    finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
                 }
 
-                finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+                results.add(result);
+            } catch (DelegatedAdministrationException e) {
+                LOG.error("Not allowed to read Realm {}", key, e);
+            } catch (Exception e) {
+                LOG.error("Could not delete Realm {}", key, e);
             }
-        } catch (Exception e) {
-            LOG.error("Could not delete {}", realm, e);
         }
 
-        return result;
+        return results;
     }
 
     private ProvisioningReport ignore(
@@ -572,43 +675,46 @@ public class RealmPullResultHandlerImpl
         LOG.debug("Process {} for {} as {}",
                 delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
 
-        Realm realm = IterableUtils.find(realmDAO.findAll(), new Predicate<Realm>() {
+        String uid = delta.getPreviousUid() == null
+                ? delta.getUid().getUidValue()
+                : delta.getPreviousUid().getUidValue();
 
-            @Override
-            public boolean evaluate(final Realm realm) {
-                JexlContext jexlContext = new MapContext();
-                JexlUtils.addFieldsToContext(realm, jexlContext);
-                String evalConnObjectLink = JexlUtils.evaluate(orgUnit.getConnObjectLink(), jexlContext);
-
-                return delta.getObject().getName().getNameValue().equals(evalConnObjectLink);
-            }
-        });
+        List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
         LOG.debug("Match found for {} as {}: {}",
-                delta.getObject().getName().getNameValue(), delta.getObject().getObjectClass(), realm);
+                delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
 
-        String realmName = delta.getUid().getUidValue();
-        Attribute nameAttr = delta.getObject().getAttributeByName(orgUnit.getExtAttrName());
-        if (nameAttr != null && nameAttr.getValue() != null && !nameAttr.getValue().isEmpty()) {
-            realmName = nameAttr.getValue().get(0).toString();
+        if (keys.size() > 1) {
+            switch (profile.getResAct()) {
+                case IGNORE:
+                    throw new IllegalStateException("More than one match " + keys);
+
+                case FIRSTMATCH:
+                    keys = keys.subList(0, 1);
+                    break;
+
+                case LASTMATCH:
+                    keys = keys.subList(keys.size() - 1, keys.size());
+                    break;
+
+                default:
+                // keep keys unmodified
+                }
         }
 
         try {
             if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
-                if (realm == null) {
+                if (keys.isEmpty()) {
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), assign(delta, realmName));
+                            profile.getResults().addAll(assign(delta, orgUnit));
                             break;
 
                         case PROVISION:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), provision(delta, realmName));
+                            profile.getResults().addAll(provision(delta, orgUnit));
                             break;
 
                         case IGNORE:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), ignore(delta, false));
+                            profile.getResults().add(ignore(delta, false));
                             break;
 
                         default:
@@ -617,32 +723,27 @@ public class RealmPullResultHandlerImpl
                 } else {
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), update(delta, realm, realmName));
+                            profile.getResults().addAll(update(delta, keys));
                             break;
 
                         case DEPROVISION:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), deprovision(delta, realm, false));
+                            profile.getResults().addAll(deprovision(delta, keys, false));
                             break;
 
                         case UNASSIGN:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), deprovision(delta, realm, true));
+                            profile.getResults().addAll(deprovision(delta, keys, true));
                             break;
 
                         case LINK:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), link(delta, realm, false));
+                            profile.getResults().addAll(link(delta, keys, false));
                             break;
 
                         case UNLINK:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), link(delta, realm, true));
+                            profile.getResults().addAll(link(delta, keys, true));
                             break;
 
                         case IGNORE:
-                            CollectionUtils.addIgnoreNull(profile.getResults(), ignore(delta, true));
+                            profile.getResults().add(ignore(delta, true));
                             break;
 
                         default:
@@ -650,10 +751,11 @@ public class RealmPullResultHandlerImpl
                     }
                 }
             } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
-                if (realm == null) {
+                if (keys.isEmpty()) {
+                    finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
                     LOG.debug("No match found for deletion");
                 } else {
-                    CollectionUtils.addIgnoreNull(profile.getResults(), delete(delta, realm));
+                    profile.getResults().addAll(delete(delta, keys));
                 }
             }
         } catch (IllegalStateException | IllegalArgumentException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
index f028b38..104276e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.AuditElements;
@@ -32,9 +33,10 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -44,10 +46,9 @@ import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
 import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@@ -59,7 +60,10 @@ public class RealmPushResultHandlerImpl
         implements SyncopePushResultHandler {
 
     @Autowired
-    protected SchedulerFactoryBean scheduler;
+    private MappingManager mappingManager;
+
+    @Autowired
+    private SchedulerFactoryBean scheduler;
 
     @Transactional(propagation = Propagation.REQUIRES_NEW)
     @Override
@@ -153,39 +157,22 @@ public class RealmPushResultHandlerImpl
         provision(update(realmTO, result), result);
     }
 
-    /**
-     * Get remote object for given realm .
-     *
-     * @param connector connector facade proxy.
-     * @param task current propagation task.
-     * @param orgUnit orgUnit
-     * @return remote connector object.
-     */
-    private ConnectorObject getRemoteObject(
-            final String realmName,
-            final Connector connector,
-            final OrgUnit orgUnit) {
-
-        final ConnectorObject[] obj = new ConnectorObject[1];
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+        ConnectorObject obj = null;
         try {
-            connector.search(orgUnit.getObjectClass(),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
-                    new ResultsHandler() {
-
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
+            Uid uid = new Uid(connObjectKey);
+
+            obj = profile.getConnector().getObject(objectClass,
+                    uid,
+                    MappingUtils.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", realmName, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
 
-        return obj[0];
+        return obj;
     }
 
     private void doHandle(final Realm realm) throws JobExecutionException {
@@ -202,10 +189,10 @@ public class RealmPushResultHandlerImpl
         Result resultStatus = null;
 
         // Try to read remote object BEFORE any actual operation
-        ConnectorObject beforeObj = getRemoteObject(
-                realm.getName(),
-                profile.getConnector(),
-                profile.getTask().getResource().getOrgUnit());
+        OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+        String connObjecKey = mappingManager.getConnObjectKeyValue(realm, orgUnit);
+
+        ConnectorObject beforeObj = getRemoteObject(connObjecKey, orgUnit.getObjectClass());
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
@@ -375,10 +362,7 @@ public class RealmPushResultHandlerImpl
                     result.setStatus(ProvisioningReport.Status.SUCCESS);
                 }
                 resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(
-                        realm.getName(),
-                        profile.getConnector(),
-                        profile.getTask().getResource().getOrgUnit());
+                output = getRemoteObject(connObjecKey, orgUnit.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
index be35d61..249e488 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -29,6 +29,7 @@ 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.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -41,6 +42,8 @@ import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.MappingManager;
@@ -159,6 +162,16 @@ public class ConnObjectUtils {
         return anyTO;
     }
 
+    public RealmTO getRealmTO(final ConnectorObject obj, final PullTask task, final OrgUnit orgUnit) {
+        RealmTO realmTO = new RealmTO();
+
+        for (OrgUnitItem item : MappingUtils.getPullItems(orgUnit)) {
+            mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), realmTO);
+        }
+
+        return realmTO;
+    }
+
     /**
      * Build {@link AnyPatch} out of connector object attributes and schema mapping.
      *
@@ -255,7 +268,7 @@ public class ConnObjectUtils {
 
         // 1. fill with data from connector object
         anyTO.setRealm(pullTask.getDestinatioRealm().getFullPath());
-        for (MappingItem item : MappingUtils.getPullMappingItems(provision)) {
+        for (MappingItem item : MappingUtils.getPullItems(provision)) {
             mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index e719a38..2c71f37 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -19,25 +19,27 @@
 package org.apache.syncope.core.provisioning.java.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.collections4.Predicate;
 import org.apache.commons.jexl3.JexlContext;
 import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.JEXLMappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
+import org.apache.syncope.core.provisioning.java.data.JEXLItemTransformerImpl;
 import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.identityconnectors.framework.common.objects.Name;
@@ -48,6 +50,8 @@ import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
 
 public final class MappingUtils {
 
@@ -64,67 +68,68 @@ public final class MappingUtils {
                 : 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();
-        }
+    public static List<? extends MappingItem> getPropagationItems(final Provision provision) {
+        return ListUtils.select(provision.getMapping().getItems(), new Predicate<MappingItem>() {
 
-        List<MappingItem> result = new ArrayList<>();
-
-        switch (purpose) {
-            case PULL:
-                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.PULL != 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:
-        }
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.getPurpose() == MappingPurpose.PROPAGATION || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
+    }
 
-        return result;
+    public static List<? extends MappingItem> getPullItems(final Provision provision) {
+        return ListUtils.select(provision.getMapping().getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.getPurpose() == MappingPurpose.PULL || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
     }
 
-    public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.PROPAGATION);
+    public static List<? extends OrgUnitItem> getPropagationItems(final OrgUnit orgUnit) {
+        return ListUtils.select(orgUnit.getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.getPurpose() == MappingPurpose.PROPAGATION || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
     }
 
-    public static List<MappingItem> getPullMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.PULL);
+    public static List<? extends OrgUnitItem> getPullItems(final OrgUnit orgUnit) {
+        return ListUtils.select(orgUnit.getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.getPurpose() == MappingPurpose.PULL || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
+    }
+
+    private static Name evaluateNAME(final String evalConnObjectLink, final String connObjectKey) {
+        // 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;
     }
 
     /**
-     * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
+     * Build __NAME__ for propagation.
+     * First look if there is a defined connObjectLink for the given resource (and in
      * this case evaluate as JEXL); otherwise, take given connObjectKey.
      *
      * @param any given any object
@@ -151,36 +156,51 @@ public final class MappingUtils {
             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);
+        return evaluateNAME(evalConnObjectLink, connObjectKey);
+    }
 
-            // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
-            LOG.debug("connObjectKey will be used just as __UID__ attribute");
+    /**
+     * Build __NAME__ for propagation.
+     * First look if there is a defined connObjectLink for the given resource (and in
+     * this case evaluate as JEXL); otherwise, take given connObjectKey.
+     *
+     * @param realm given any object
+     * @param orgUnit external resource
+     * @param connObjectKey connector object key
+     * @return the value to be propagated as __NAME__
+     */
+    public static Name evaluateNAME(final Realm realm, final OrgUnit orgUnit, 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 '{}': ", orgUnit.getResource());
         }
 
-        return name;
+        // Evaluate connObjectKey expression
+        String connObjectLink = orgUnit == null
+                ? null
+                : orgUnit.getConnObjectLink();
+        String evalConnObjectLink = null;
+        if (StringUtils.isNotBlank(connObjectLink)) {
+            JexlContext jexlContext = new MapContext();
+            JexlUtils.addFieldsToContext(realm, jexlContext);
+            evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
+        }
+
+        return evaluateNAME(evalConnObjectLink, connObjectKey);
     }
 
-    private static List<MappingItemTransformer> getMappingItemTransformers(
+    private static List<ItemTransformer> getMappingItemTransformers(
             final String propagationJEXLTransformer,
             final String pullJEXLTransformer,
             final List<String> mappingItemTransformerClassNames) {
 
-        List<MappingItemTransformer> result = new ArrayList<>();
+        List<ItemTransformer> result = new ArrayList<>();
 
         // First consider the JEXL transformation expressions
         if (StringUtils.isNotBlank(propagationJEXLTransformer) || StringUtils.isNotBlank(pullJEXLTransformer)) {
-            JEXLMappingItemTransformer jexlTransformer =
-                    (JEXLMappingItemTransformer) ApplicationContextProvider.getBeanFactory().
-                            createBean(JEXLMappingItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME,
+            JEXLItemTransformer jexlTransformer =
+                    (JEXLItemTransformer) ApplicationContextProvider.getBeanFactory().
+                            createBean(JEXLItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME,
                                     false);
 
             jexlTransformer.setPropagationJEXL(propagationJEXLTransformer);
@@ -193,7 +213,7 @@ public final class MappingUtils {
             try {
                 Class<?> transformerClass = ClassUtils.getClass(className);
 
-                result.add((MappingItemTransformer) ApplicationContextProvider.getBeanFactory().
+                result.add((ItemTransformer) ApplicationContextProvider.getBeanFactory().
                         createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
             } catch (Exception e) {
                 LOG.error("Could not instantiate {}, ignoring...", className, e);
@@ -203,28 +223,28 @@ public final class MappingUtils {
         return result;
     }
 
-    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItemTO mappingItem) {
+    public static List<ItemTransformer> getItemTransformers(final ItemTO item) {
         return getMappingItemTransformers(
-                mappingItem.getPropagationJEXLTransformer(),
-                mappingItem.getPullJEXLTransformer(),
-                mappingItem.getMappingItemTransformerClassNames());
+                item.getPropagationJEXLTransformer(),
+                item.getPullJEXLTransformer(),
+                item.getTransformerClassNames());
     }
 
-    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
+    public static List<ItemTransformer> getItemTransformers(final Item item) {
         return getMappingItemTransformers(
-                mappingItem.getPropagationJEXLTransformer(),
-                mappingItem.getPullJEXLTransformer(),
-                mappingItem.getMappingItemTransformerClassNames());
+                item.getPropagationJEXLTransformer(),
+                item.getPullJEXLTransformer(),
+                item.getTransformerClassNames());
     }
 
     /**
      * Build options for requesting all mapped connector attributes.
      *
-     * @param mapItems mapping items
+     * @param iterator items
      * @return options for requesting all mapped connector attributes
      * @see OperationOptions
      */
-    public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
+    public static OperationOptions buildOperationOptions(final Iterator<? extends Item> iterator) {
         OperationOptionsBuilder builder = new OperationOptionsBuilder();
 
         Set<String> attrsToGet = new HashSet<>();
@@ -232,10 +252,10 @@ public final class MappingUtils {
         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());
+        while (iterator.hasNext()) {
+            Item item = iterator.next();
+            if (item.getPurpose() != MappingPurpose.NONE) {
+                attrsToGet.add(item.getExtAttrName());
             }
         }
 
@@ -246,17 +266,6 @@ public final class MappingUtils {
     }
 
     /**
-     * Build options for requesting connector attributes for the given orgUnit.
-     *
-     * @param orgUnit orgUnit
-     * @return options for requesting connector attributes for the given orgUnit
-     * @see OperationOptions
-     */
-    public static OperationOptions buildOperationOptions(final OrgUnit orgUnit) {
-        return new OperationOptionsBuilder().setAttributesToGet(Name.NAME, Uid.NAME, orgUnit.getExtAttrName()).build();
-    }
-
-    /**
      * Private default constructor, for static-only classes.
      */
     private MappingUtils() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
index 714dcff..bc7329a 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
@@ -28,7 +28,7 @@ import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -122,7 +122,7 @@ public class ResourceDataBinderTest extends AbstractTest {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("userId");
         item.setExtAttrName("campo1");
         item.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
index 2597f42..8ea1671 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
@@ -23,9 +23,9 @@ import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -40,13 +40,13 @@ public class SAML2IdPMappingPanel extends AbstractMappingPanel {
     public SAML2IdPMappingPanel(
             final String id,
             final SAML2IdPTO idpTO,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ItemTransformersTogglePanel mapItemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
         super(id,
                 mapItemTransformers,
                 jexlTransformers,
-                new ListModel<MappingItemTO>(idpTO.getMappingItems()),
+                new ListModel<ItemTO>(idpTO.getMappingItems()),
                 true,
                 true,
                 MappingPurpose.NONE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index d824807..aa9ea0f 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -32,8 +32,8 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.wicket.Component;
@@ -68,8 +68,8 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
         Mapping mapping = new Mapping(modelObject);
         mapping.setOutputMarkupId(true);
 
-        MappingItemTransformersTogglePanel mapItemTransformers =
-                new MappingItemTransformersTogglePanel(mapping, pageRef);
+        ItemTransformersTogglePanel mapItemTransformers =
+                new ItemTransformersTogglePanel(mapping, pageRef);
         addOuterObject(mapItemTransformers);
         JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
         addOuterObject(jexlTransformers);
@@ -133,10 +133,10 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
     @Override
     protected Serializable onApplyInternal(final SAML2IdPTO modelObject) {
         long connObjectKeyCount = IterableUtils.countMatches(
-                modelObject.getMappingItems(), new Predicate<MappingItemTO>() {
+                modelObject.getMappingItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
index 109af15..089908e 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
@@ -51,7 +51,7 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
 
     private boolean logoutSupported;
 
-    private final List<MappingItemTO> mappingItems = new ArrayList<>();
+    private final List<ItemTO> mappingItems = new ArrayList<>();
 
     @Override
     public String getKey() {
@@ -112,24 +112,24 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
         this.logoutSupported = logoutSupported;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
-        return IterableUtils.find(getMappingItems(), new Predicate<MappingItemTO>() {
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getMappingItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });
     }
 
-    protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
         connObjectItem.setMandatoryCondition("true");
         connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);
     }
 
-    public boolean setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         return connObjectKeyItem == null
                 ? remove(getConnObjectKeyItem())
                 : addConnObjectKeyItem(connObjectKeyItem);
@@ -138,15 +138,15 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
     @XmlElementWrapper(name = "mappingItems")
     @XmlElement(name = "mappingItem")
     @JsonProperty("mappingItems")
-    public List<MappingItemTO> getMappingItems() {
+    public List<ItemTO> getMappingItems() {
         return mappingItems;
     }
 
-    public boolean add(final MappingItemTO item) {
+    public boolean add(final ItemTO item) {
         return item == null ? false : this.mappingItems.contains(item) || this.mappingItems.add(item);
     }
 
-    public boolean remove(final MappingItemTO item) {
+    public boolean remove(final ItemTO item) {
         return this.mappingItems.remove(item);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
index 95094e9..bb26b34 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
@@ -30,7 +30,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
@@ -154,7 +154,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
                 idpTO.setMetadata(Base64.encodeBase64String(baos.toByteArray()));
             }
 
-            MappingItemTO connObjectKeyItem = new MappingItemTO();
+            ItemTO connObjectKeyItem = new ItemTO();
             connObjectKeyItem.setIntAttrName("username");
             connObjectKeyItem.setExtAttrName("NameID");
             idpTO.setConnObjectKeyItem(connObjectKeyItem);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 91e9ff0..59d6c2c 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -43,7 +43,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.SAML2RequestTO;
 import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -66,7 +66,6 @@ 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.IntAttrName;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
@@ -119,6 +118,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Component
 public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
@@ -340,11 +340,11 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         return requestTO;
     }
 
-    private List<String> findMatchingUser(final String keyValue, final MappingItemTO connObjectKeyItem) {
+    private List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
         List<String> result = new ArrayList<>();
 
         String transformed = keyValue;
-        for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(connObjectKeyItem)) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
             List<Object> output = transformer.beforePull(
                     null,
                     null,

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
index a5ab6c3..ed244d0 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
@@ -28,7 +28,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import net.shibboleth.utilities.java.support.xml.XMLParserException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.core.logic.init.SAML2SPLoader;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
@@ -66,7 +66,7 @@ public class SAML2IdPCache {
 
     public SAML2IdPEntity put(
             final EntityDescriptor entityDescriptor,
-            final MappingItemTO connObjectKeyItem,
+            final ItemTO connObjectKeyItem,
             final boolean useDeflateEncoding,
             final SAML2BindingType bindingType)
             throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
index dd07cdd..b747c32 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
@@ -31,7 +31,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.metadata.Endpoint;
@@ -55,7 +55,7 @@ public class SAML2IdPEntity {
 
     private SAML2BindingType bindingType;
 
-    private MappingItemTO connObjectKeyItem;
+    private ItemTO connObjectKeyItem;
 
     private final Map<String, Endpoint> ssoBindings = new HashMap<>();
 
@@ -67,7 +67,7 @@ public class SAML2IdPEntity {
 
     public SAML2IdPEntity(
             final EntityDescriptor entityDescriptor,
-            final MappingItemTO connObjectKeyItem,
+            final ItemTO connObjectKeyItem,
             final boolean useDeflateEncoding,
             final SAML2BindingType bindingType,
             final String keyPass)
@@ -141,11 +141,11 @@ public class SAML2IdPEntity {
         this.bindingType = bindingType;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
+    public ItemTO getConnObjectKeyItem() {
         return connObjectKeyItem;
     }
 
-    public void setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    public void setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         this.connObjectKeyItem = connObjectKeyItem;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
index 9869500..3e80bed 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
@@ -24,7 +24,7 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP> {
 
@@ -61,12 +61,12 @@ public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP
         }
 
         for (MappingItem item : value.getMappingItems()) {
-            for (String className : item.getMappingItemTransformerClassNames()) {
+            for (String className : item.getTransformerClassNames()) {
                 Class<?> actionsClass = null;
                 boolean isAssignable = false;
                 try {
                     actionsClass = Class.forName(className);
-                    isAssignable = MappingItemTransformer.class.isAssignableFrom(actionsClass);
+                    isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass);
                 } catch (Exception e) {
                     LOG.error("Invalid MappingItemTransformer specified: {}", className, e);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
index 5eba217..f9f16ab 100644
--- a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
+++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
@@ -22,7 +22,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -87,10 +87,10 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
         SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
                 ClientExceptionType.RequiredValuesMissing);
 
-        for (MappingItemTO itemTO : idpTO.getMappingItems()) {
+        for (ItemTO itemTO : idpTO.getMappingItems()) {
             if (itemTO == null) {
-                LOG.error("Null {}", MappingItemTO.class.getSimpleName());
-                invalidMapping.getElements().add("Null " + MappingItemTO.class.getSimpleName());
+                LOG.error("Null {}", ItemTO.class.getSimpleName());
+                invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
             } else if (itemTO.getIntAttrName() == null) {
                 requiredValuesMissing.getElements().add("intAttrName");
                 scce.addException(requiredValuesMissing);
@@ -194,7 +194,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
 
     private void populateMappingTO(final SAML2IdP idp, final SAML2IdPTO idpTO) {
         for (MappingItem item : idp.getMappingItems()) {
-            MappingItemTO itemTO = new MappingItemTO();
+            ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
             BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
             itemTO.setPurpose(MappingPurpose.NONE);


[12/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
[SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys


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

Branch: refs/heads/master
Commit: eebca673ec43f26c711c5e16495427800180570a
Parents: 3faef35
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jul 18 12:20:31 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jul 18 12:22:30 2017 +0200

----------------------------------------------------------------------
 .../syncope/client/cli/commands/info/Info.java  |   2 +-
 .../resource/ResourceResultManager.java         |   8 +-
 .../client/console/bulk/BulkContent.java        |   6 +-
 .../console/commons/status/StatusBean.java      |  31 +-
 .../console/commons/status/StatusUtils.java     |  38 +-
 .../client/console/panels/ConnObjects.java      |   9 +-
 .../client/console/panels/ListViewPanel.java    |   4 +-
 .../panels/ProvisionAuxClassesPanel.java        |  29 +-
 .../console/rest/AbstractAnyRestClient.java     |   5 -
 .../client/console/rest/AnyTypeRestClient.java  |   7 +
 .../console/status/AnyStatusDirectoryPanel.java |   8 +-
 .../console/status/ChangePasswordModal.java     |   4 +-
 .../status/ResourceStatusDirectoryPanel.java    |   3 +-
 .../console/status/ResourceStatusModal.java     |  28 +-
 .../html/form/ActionLinksTogglePanel.java       |   2 +-
 .../console/widgets/ItemTransformerWidget.java  |  83 +++
 .../console/widgets/JEXLTransformerWidget.java  |  20 +-
 .../widgets/MappingItemTransformerWidget.java   |  83 ---
 .../console/wizards/AbstractMappingPanel.java   |  64 +-
 .../client/console/wizards/any/StatusPanel.java |   8 +-
 .../console/wizards/any/UserWizardBuilder.java  |   2 +-
 .../resources/ItemTransformersTogglePanel.java  | 118 ++++
 .../resources/JEXLTransformersTogglePanel.java  |   8 +-
 .../MappingItemTransformersTogglePanel.java     | 121 ----
 .../resources/ProvisionWizardBuilder.java       | 102 +--
 .../wizards/resources/ResourceMappingPanel.java |  75 ++-
 .../wizards/resources/ResourceProvision.java    | 151 +++++
 .../resources/ResourceProvisionPanel.java       | 247 ++-----
 .../META-INF/resources/css/syncopeConsole.css   |   6 +-
 .../widgets/ItemTransformerWidget.properties    |  18 +
 .../widgets/ItemTransformerWidget_it.properties |  18 +
 .../ItemTransformerWidget_pt_BR.properties      |  18 +
 .../widgets/ItemTransformerWidget_ru.properties |  19 +
 .../MappingItemTransformerWidget.properties     |  18 -
 .../MappingItemTransformerWidget_it.properties  |  18 -
 ...appingItemTransformerWidget_pt_BR.properties |  18 -
 .../MappingItemTransformerWidget_ru.properties  |  19 -
 .../console/wizards/AbstractMappingPanel.html   |   2 +-
 .../resources/ItemTransformersTogglePanel.html  |  32 +
 .../ItemTransformersTogglePanel.properties      |  19 +
 .../ItemTransformersTogglePanel_it.properties   |  19 +
 ...ItemTransformersTogglePanel_pt_BR.properties |  19 +
 .../ItemTransformersTogglePanel_ru.properties   |  20 +
 .../MappingItemTransformersTogglePanel.html     |  32 -
 ...appingItemTransformersTogglePanel.properties |  19 -
 ...ingItemTransformersTogglePanel_it.properties |  19 -
 ...ItemTransformersTogglePanel_pt_BR.properties |  19 -
 ...ingItemTransformersTogglePanel_ru.properties |  20 -
 .../resources/ResourceProvisionPanel.html       |   8 -
 .../resources/ResourceProvisionPanel.properties |   5 -
 .../ResourceProvisionPanel_it.properties        |   5 -
 .../ResourceProvisionPanel_pt_BR.properties     |   5 -
 .../ResourceProvisionPanel_ru.properties        |   5 -
 .../syncope/common/lib/info/PlatformInfo.java   |  12 +-
 .../syncope/common/lib/to/ItemContainerTO.java  |  32 +
 .../apache/syncope/common/lib/to/ItemTO.java    | 163 +++++
 .../syncope/common/lib/to/MappingItemTO.java    | 163 -----
 .../apache/syncope/common/lib/to/MappingTO.java |  28 +-
 .../apache/syncope/common/lib/to/OrgUnitTO.java |  62 +-
 .../syncope/core/logic/ResourceLogic.java       |  66 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |   4 +-
 .../init/ClassPathScanImplementationLookup.java |  12 +-
 .../persistence/api/ImplementationLookup.java   |   2 +-
 .../core/persistence/api/dao/RealmDAO.java      |   2 +
 .../api/entity/LinkingMappingItem.java          |   2 +-
 .../persistence/api/entity/resource/Item.java   |  60 ++
 .../api/entity/resource/Mapping.java            |   8 +-
 .../api/entity/resource/MappingItem.java        |  40 +-
 .../api/entity/resource/OrgUnit.java            |  12 +-
 .../api/entity/resource/OrgUnitItem.java        |  26 +
 .../core/persistence/jpa/dao/JPARealmDAO.java   |  11 +
 .../jpa/entity/JPAEntityFactory.java            |   4 +
 .../jpa/entity/resource/AbstractItem.java       | 176 +++++
 .../jpa/entity/resource/JPAMapping.java         |   4 +-
 .../jpa/entity/resource/JPAMappingItem.java     | 157 +----
 .../jpa/entity/resource/JPAOrgUnit.java         |  47 +-
 .../jpa/entity/resource/JPAOrgUnitItem.java     |  72 +++
 .../entity/ExternalResourceValidator.java       |  74 ++-
 .../test/resources/domains/MasterContent.xml    |  12 +-
 .../core/provisioning/api/MappingManager.java   |  32 +
 .../provisioning/api/data/ItemTransformer.java  |  60 ++
 .../api/data/JEXLItemTransformer.java           |  30 +
 .../api/data/JEXLMappingItemTransformer.java    |  30 -
 .../api/data/MappingItemTransformer.java        |  60 --
 .../provisioning/api/pushpull/PullActions.java  |   8 +-
 .../provisioning/java/MappingManagerImpl.java   | 173 ++++-
 .../java/data/AbstractAnyDataBinder.java        |   4 +-
 .../java/data/DefaultItemTransformer.java       |  47 ++
 .../data/DefaultMappingItemTransformer.java     |  54 --
 .../java/data/JEXLItemTransformerImpl.java      | 102 +++
 .../data/JEXLMappingItemTransformerImpl.java    |  99 ---
 .../java/data/ResourceDataBinderImpl.java       |  95 ++-
 .../AbstractPropagationTaskExecutor.java        |  47 +-
 .../propagation/PropagationManagerImpl.java     |  36 +-
 .../pushpull/AbstractPullResultHandler.java     |  38 +-
 .../java/pushpull/DBPasswordPullActions.java    |   5 +-
 .../java/pushpull/DefaultPullActions.java       |   5 +-
 .../java/pushpull/LDAPPasswordPullActions.java  |   5 +-
 .../pushpull/PlainAttrsPullCorrelationRule.java |   6 +-
 .../java/pushpull/PullJobDelegate.java          |  15 +-
 .../provisioning/java/pushpull/PullUtils.java   |  65 +-
 .../pushpull/RealmPullResultHandlerImpl.java    | 638 +++++++++++--------
 .../pushpull/RealmPushResultHandlerImpl.java    |  62 +-
 .../java/utils/ConnObjectUtils.java             |  15 +-
 .../provisioning/java/utils/MappingUtils.java   | 211 +++---
 .../java/ResourceDataBinderTest.java            |   4 +-
 .../console/wizards/SAML2IdPMappingPanel.java   |   8 +-
 .../console/wizards/SAML2IdPWizardBuilder.java  |  12 +-
 .../syncope/common/lib/to/SAML2IdPTO.java       |  18 +-
 .../syncope/core/logic/SAML2IdPLogic.java       |   4 +-
 .../apache/syncope/core/logic/SAML2SPLogic.java |   8 +-
 .../syncope/core/logic/saml2/SAML2IdPCache.java |   4 +-
 .../core/logic/saml2/SAML2IdPEntity.java        |  10 +-
 .../validation/entity/SAML2IdPValidator.java    |   6 +-
 .../java/data/SAML2IdPDataBinderImpl.java       |  10 +-
 .../core/reference/ITImplementationLookup.java  |   8 +-
 .../core/reference/PrefixItemTransformer.java   |  66 ++
 .../reference/PrefixMappingItemTransformer.java |  66 --
 .../fit/core/reference/TestPullActions.java     |   4 +-
 .../syncope/fit/console/BulkActionITCase.java   |   6 +-
 .../syncope/fit/console/RealmsITCase.java       |  28 +-
 .../syncope/fit/console/TopologyITCase.java     |  40 +-
 .../syncope/fit/core/ConnectorITCase.java       |   4 +-
 .../apache/syncope/fit/core/GroupITCase.java    |   6 +-
 .../syncope/fit/core/MembershipITCase.java      |  12 +-
 .../syncope/fit/core/MigrationITCase.java       |  34 +-
 .../syncope/fit/core/MultitenancyITCase.java    |  10 +-
 .../syncope/fit/core/PropagationTaskITCase.java |  10 +-
 .../apache/syncope/fit/core/PullTaskITCase.java |  19 +-
 .../apache/syncope/fit/core/PushTaskITCase.java |   4 +-
 .../apache/syncope/fit/core/RealmITCase.java    |  52 +-
 .../apache/syncope/fit/core/ResourceITCase.java |  60 +-
 .../apache/syncope/fit/core/SAML2ITCase.java    |   4 +-
 .../syncope/fit/core/UserIssuesITCase.java      |  12 +-
 .../apache/syncope/fit/core/VirAttrITCase.java  |  16 +-
 135 files changed, 3047 insertions(+), 2357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
index 369ee8e..7df6fb7 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
@@ -131,7 +131,7 @@ public class Info {
 
     public void mappingItemTransformers() {
         try {
-            infoResultManager.printMappingItemTransformers(platformInfo.getMappingItemTransformers());
+            infoResultManager.printMappingItemTransformers(platformInfo.getItemTransformers());
         } catch (final Exception ex) {
             LOG.error("Information error", ex);
             infoResultManager.genericError(ex.getMessage());

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
index aefb7c1..7e57e01 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.cli.commands.resource;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.client.cli.commands.CommonsResultManager;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -74,8 +74,8 @@ public class ResourceResultManager extends CommonsResultManager {
         printMappingItem(mappingTO.getItems());
     }
 
-    private void printMappingItem(final List<MappingItemTO> mappingItemTOs) {
-        for (final MappingItemTO mappingItemTO : mappingItemTOs) {
+    private void printMappingItem(final List<ItemTO> mappingItemTOs) {
+        for (final ItemTO mappingItemTO : mappingItemTOs) {
             System.out.println("             mapping key: " + mappingItemTO.getKey());
             System.out.println("             internal attribute name: " + mappingItemTO.getIntAttrName());
             System.out.println("             external attribute name: " + mappingItemTO.getExtAttrName());
@@ -85,7 +85,7 @@ public class ResourceResultManager extends CommonsResultManager {
             System.out.println("             JEXL pull transformer: "
                     + mappingItemTO.getPullJEXLTransformer());
             System.out.println("             transformers classes: "
-                    + mappingItemTO.getMappingItemTransformerClassNames());
+                    + mappingItemTO.getTransformerClassNames());
             System.out.println("             purpose: " + mappingItemTO.getPurpose());
             System.out.println("             connector object key: " + mappingItemTO.isConnObjectKey());
             System.out.println("             password: " + mappingItemTO.isPassword());

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
index 2a46141..de3ceb7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
@@ -171,11 +171,11 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                             for (T bean : items) {
                                 final StatusBean sb = StatusBean.class.cast(bean);
                                 final List<StatusBean> sblist;
-                                if (beans.containsKey(sb.getAnyKey())) {
-                                    sblist = beans.get(sb.getAnyKey());
+                                if (beans.containsKey(sb.getKey())) {
+                                    sblist = beans.get(sb.getKey());
                                 } else {
                                     sblist = new ArrayList<>();
-                                    beans.put(sb.getAnyKey(), sblist);
+                                    beans.put(sb.getKey(), sblist);
                                 }
                                 sblist.add(sb);
                             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
index a34425a..c8bba79 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
@@ -25,17 +25,18 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 
 public class StatusBean implements Serializable {
 
     private static final long serialVersionUID = -5207260204921071129L;
 
-    private final String anyKey;
+    private final String key;
 
-    private final String anyName;
+    private final String name;
 
-    private final String resourceName;
+    private final String resource;
 
     private String connObjectLink;
 
@@ -44,11 +45,17 @@ public class StatusBean implements Serializable {
     private boolean linked = true;
 
     public StatusBean(final AnyTO any, final String resourceName) {
-        this.anyKey = any.getKey();
-        this.anyName = any instanceof UserTO
+        this.key = any.getKey();
+        this.name = any instanceof UserTO
                 ? ((UserTO) any).getUsername()
                 : any instanceof GroupTO ? ((GroupTO) any).getName() : String.valueOf(any.getKey());
-        this.resourceName = resourceName;
+        this.resource = resourceName;
+    }
+
+    public StatusBean(final RealmTO realm, final String resourceName) {
+        this.key = realm.getKey();
+        this.name = realm.getFullPath();
+        this.resource = resourceName;
     }
 
     public String getConnObjectLink() {
@@ -59,8 +66,8 @@ public class StatusBean implements Serializable {
         this.connObjectLink = connObjectLink;
     }
 
-    public String getResourceName() {
-        return resourceName;
+    public String getResource() {
+        return resource;
     }
 
     public Status getStatus() {
@@ -71,12 +78,12 @@ public class StatusBean implements Serializable {
         this.status = status;
     }
 
-    public String getAnyKey() {
-        return anyKey;
+    public String getKey() {
+        return key;
     }
 
-    public String getAnyName() {
-        return anyName;
+    public String getName() {
+        return name;
     }
 
     public boolean isLinked() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index 6da9246..8a9aa09 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.patch.StatusPatch;
 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.RealmTO;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.basic.Label;
@@ -88,7 +89,7 @@ public class StatusUtils implements Serializable {
             final AnyTO anyTO,
             final String resourceName,
             final ConnObjectTO objectTO,
-            final boolean isGroup) {
+            final boolean notUser) {
 
         final StatusBean statusBean = new StatusBean(anyTO, resourceName);
 
@@ -96,7 +97,32 @@ public class StatusUtils implements Serializable {
             final Boolean enabled = isEnabled(objectTO);
 
             final Status status = enabled == null
-                    ? (isGroup ? Status.ACTIVE : Status.UNDEFINED)
+                    ? (notUser ? Status.ACTIVE : Status.UNDEFINED)
+                    : enabled
+                            ? Status.ACTIVE
+                            : Status.SUSPENDED;
+
+            String connObjectLink = getConnObjectLink(objectTO);
+
+            statusBean.setStatus(status);
+            statusBean.setConnObjectLink(connObjectLink);
+        }
+
+        return statusBean;
+    }
+
+    public StatusBean getStatusBean(
+            final RealmTO anyTO,
+            final String resourceName,
+            final ConnObjectTO objectTO) {
+
+        final StatusBean statusBean = new StatusBean(anyTO, resourceName);
+
+        if (objectTO != null) {
+            final Boolean enabled = isEnabled(objectTO);
+
+            final Status status = enabled == null
+                    ? Status.ACTIVE
                     : enabled
                             ? Status.ACTIVE
                             : Status.SUSPENDED;
@@ -129,10 +155,10 @@ public class StatusUtils implements Serializable {
         builder.value(password);
 
         for (StatusBean status : statuses) {
-            if (Constants.SYNCOPE.equalsIgnoreCase(status.getResourceName())) {
+            if (Constants.SYNCOPE.equalsIgnoreCase(status.getResource())) {
                 builder.onSyncope(true);
             } else {
-                builder.resource(status.getResourceName());
+                builder.resource(status.getResource());
             }
         }
         return builder.build();
@@ -150,10 +176,10 @@ public class StatusUtils implements Serializable {
             if (enable == null
                     || (enable && !status.getStatus().isActive()) || (!enable && status.getStatus().isActive())) {
 
-                if ("syncope".equalsIgnoreCase(status.getResourceName())) {
+                if ("syncope".equalsIgnoreCase(status.getResource())) {
                     statusPatch.setOnSyncope(true);
                 } else {
-                    statusPatch.getResources().add(status.getResourceName());
+                    statusPatch.getResources().add(status.getResource());
                 }
 
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
index 595ff5a..d29ce1a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
@@ -19,10 +19,12 @@
 package org.apache.syncope.client.console.panels;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -48,16 +50,17 @@ public class ConnObjects extends Panel implements ModalPanel {
     public ConnObjects(final ResourceTO resource, final PageReference pageRef) {
         super(BaseModal.CONTENT_ID);
 
-        List<String> availableAnyTypes = CollectionUtils.collect(resource.getProvisions(),
-                new Transformer<ProvisionTO, String>() {
+        List<String> availableAnyTypes = CollectionUtils.collect(
+                resource.getProvisions(), new Transformer<ProvisionTO, String>() {
 
             @Override
             public String transform(final ProvisionTO provision) {
                 return provision.getAnyType();
             }
         }, new ArrayList<String>());
+        Collections.sort(availableAnyTypes, new AnyTypeRestClient.AnyTypeKeyComparator());
         if (resource.getOrgUnit() != null) {
-            availableAnyTypes.add(SyncopeConstants.REALM_ANYTYPE);
+            availableAnyTypes.add(0, SyncopeConstants.REALM_ANYTYPE);
         }
 
         anyTypes = new AjaxDropDownChoicePanel<>("anyTypes", "anyTypes", new Model<String>());

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 16c4b77..e028cc3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -241,7 +241,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             super(pageRef);
             this.reference = reference;
             this.items = null;
-            this.actions = new ActionsPanel<T>("actions", null);
+            this.actions = new ActionsPanel<>("actions", null);
         }
 
         public Builder<T> setModel(final IModel<? extends Collection<T>> model) {
@@ -376,7 +376,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             return new ListViewPanel<T>(
                     id, items, reference, includes, actions, check, reuseItem, wizardInModal, model) {
 
-                private static final long serialVersionUID = 1L;
+                private static final long serialVersionUID = -1715389337530657988L;
 
                 @Override
                 protected Component getValueComponent(final String key, final T bean) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
index 3e7116c..574939a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.panels;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
@@ -27,6 +28,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.util.ListModel;
 
@@ -47,16 +49,27 @@ public class ProvisionAuxClassesPanel extends Panel {
     protected void onBeforeRender() {
         super.onBeforeRender();
 
-        AnyTypeTO anyType = new AnyTypeRestClient().read(provisionTO.getAnyType());
-        List<String> choices = new ArrayList<>();
-        for (AnyTypeClassTO aux : new AnyTypeClassRestClient().list()) {
-            if (!anyType.getClasses().contains(aux.getKey())) {
-                choices.add(aux.getKey());
+        IModel<List<String>> model;
+        List<String> choices;
+        if (provisionTO == null) {
+            model = new ListModel<>(Collections.<String>emptyList());
+            choices = Collections.emptyList();
+        } else {
+            model = new PropertyModel<>(provisionTO, "auxClasses");
+
+            AnyTypeTO anyType = new AnyTypeRestClient().read(provisionTO.getAnyType());
+            choices = new ArrayList<>();
+            for (AnyTypeClassTO aux : new AnyTypeClassRestClient().list()) {
+                if (!anyType.getClasses().contains(aux.getKey())) {
+                    choices.add(aux.getKey());
+                }
             }
         }
-        addOrReplace(new AjaxPalettePanel.Builder<String>().build("auxClasses",
-                new PropertyModel<List<String>>(provisionTO, "auxClasses"),
-                new ListModel<>(choices)).hideLabel().setOutputMarkupId(true));
+        addOrReplace(
+                new AjaxPalettePanel.Builder<String>().build("auxClasses", model, new ListModel<>(choices)).
+                        hideLabel().
+                        setOutputMarkupId(true).
+                        setEnabled(provisionTO != null));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
index 9d7d1d7..1386e62 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
@@ -28,7 +28,6 @@ import org.apache.syncope.common.lib.patch.AssociationPatch;
 import org.apache.syncope.common.lib.patch.DeassociationPatch;
 import org.apache.syncope.common.lib.patch.StatusPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.ResourceAssociationAction;
@@ -188,8 +187,4 @@ public abstract class AbstractAnyRestClient<TO extends AnyTO, P extends AnyPatch
         }
         return result;
     }
-
-    public BulkActionResult bulkAction(final BulkAction action) {
-        return getService(getAnyServiceClass()).bulk(action).readEntity(BulkActionResult.class);
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
index 86d27c1..fc1e004 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
@@ -24,6 +24,7 @@ import java.util.Comparator;
 import java.util.List;
 import org.apache.commons.collections4.ComparatorUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
@@ -103,6 +104,12 @@ public class AnyTypeRestClient extends BaseRestClient {
 
         @Override
         public int compare(final String o1, final String o2) {
+            if (SyncopeConstants.REALM_ANYTYPE.equals(o1)) {
+                return -1;
+            }
+            if (SyncopeConstants.REALM_ANYTYPE.equals(o2)) {
+                return 1;
+            }
             if (AnyTypeKind.USER.name().equals(o1)) {
                 return -1;
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index 992f3fb..6fcc84b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -121,7 +121,7 @@ public class AnyStatusDirectoryPanel
                     final String componentId,
                     final IModel<StatusBean> model) {
 
-                cellItem.add(new Label(componentId, model.getObject().getResourceName()) {
+                cellItem.add(new Label(componentId, model.getObject().getResource()) {
 
                     private static final long serialVersionUID = 8432079838783825801L;
 
@@ -171,14 +171,14 @@ public class AnyStatusDirectoryPanel
             @Override
             protected boolean statusCondition(final StatusBean bean) {
                 return bean != null && bean.getConnObjectLink() != null
-                        && !bean.getResourceName().equalsIgnoreCase(Constants.SYNCOPE);
+                        && !bean.getResource().equalsIgnoreCase(Constants.SYNCOPE);
             }
 
             @Override
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
-                multiLevelPanelRef.next(bean.getResourceName(),
+                multiLevelPanelRef.next(bean.getResource(),
                         new ConnObjectDetails(resourceRestClient.readConnObject(
-                                bean.getResourceName(), anyTO.getType(), anyTO.getKey())), target);
+                                bean.getResource(), anyTO.getType(), anyTO.getKey())), target);
                 target.add(multiLevelPanelRef);
                 AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
index dff996f..336f4d1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
@@ -80,10 +80,10 @@ public class ChangePasswordModal extends AbstractModalPanel<AnyWrapper<UserTO>>
                 final List<String> resources = new ArrayList<String>();
                 boolean isOnSyncope = false;
                 for (StatusBean sb : statusModel.getObject()) {
-                    if (sb.getResourceName().equals(Constants.SYNCOPE)) {
+                    if (sb.getResource().equals(Constants.SYNCOPE)) {
                         isOnSyncope = true;
                     } else {
-                        resources.add(sb.getResourceName());
+                        resources.add(sb.getResource());
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
index 93a0ffa..2844a74 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
@@ -36,6 +36,7 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -145,7 +146,7 @@ public class ResourceStatusDirectoryPanel
 
     @Override
     protected ResourceStatusDataProvider dataProvider() {
-        return new ResourceStatusDataProvider(type, resourceTO.getKey(), rows, "/");
+        return new ResourceStatusDataProvider(type, resourceTO.getKey(), rows, SyncopeConstants.ROOT_REALM);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
index 1a379a9..960bd12 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
@@ -18,7 +18,11 @@
  */
 package org.apache.syncope.client.console.status;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.status.StatusBean;
@@ -28,11 +32,12 @@ import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
 
 public class ResourceStatusModal extends StatusModal<ResourceTO> {
@@ -44,23 +49,26 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
     public ResourceStatusModal(
             final BaseModal<?> baseModal,
             final PageReference pageReference,
-            final ResourceTO resourceTO) {
+            final ResourceTO resource) {
 
-        super(baseModal, pageReference, resourceTO, null, false);
+        super(baseModal, pageReference, resource, null, false);
 
-        final LoadableDetachableModel<List<String>> types = new LoadableDetachableModel<List<String>>() {
-
-            private static final long serialVersionUID = 5275935387613157437L;
+        List<String> availableAnyTypes = CollectionUtils.collect(
+                resource.getProvisions(), new Transformer<ProvisionTO, String>() {
 
             @Override
-            protected List<String> load() {
-                return new AnyTypeRestClient().list();
+            public String transform(final ProvisionTO provision) {
+                return provision.getAnyType();
             }
-        };
+        }, new ArrayList<String>());
+        Collections.sort(availableAnyTypes, new AnyTypeRestClient.AnyTypeKeyComparator());
+        if (resource.getOrgUnit() != null) {
+            availableAnyTypes.add(0, SyncopeConstants.REALM_ANYTYPE);
+        }
 
         AjaxDropDownChoicePanel<String> anyTypes =
                 new AjaxDropDownChoicePanel<>("anyTypes", "anyTypes", typeModel, false);
-        anyTypes.setChoices(types);
+        anyTypes.setChoices(availableAnyTypes);
         anyTypes.hideLabel();
         add(anyTypes);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
index 78c175a..fb8ab83 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
@@ -99,7 +99,7 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
         } else if (modelObject instanceof EntityTO) {
             header = ((EntityTO) modelObject).getKey();
         } else if (modelObject instanceof StatusBean) {
-            header = ((StatusBean) modelObject).getResourceName();
+            header = ((StatusBean) modelObject).getResource();
         } else if (modelObject instanceof PolicyRuleWrapper) {
             header = ((PolicyRuleWrapper) modelObject).getName();
         } else if (modelObject instanceof PolicyRuleWrapper) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
new file mode 100644
index 0000000..9aa4142
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconTypeBuilder;
+import java.util.List;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class ItemTransformerWidget extends AlertWidget<String> {
+
+    private static final long serialVersionUID = 7667120094526529934L;
+
+    private final ItemTO item;
+
+    private final ItemTransformersTogglePanel transformers;
+
+    public ItemTransformerWidget(
+            final String id,
+            final ItemTO item,
+            final ItemTransformersTogglePanel transformers) {
+
+        super(id);
+        this.item = item;
+        this.transformers = transformers;
+        setOutputMarkupId(true);
+    }
+
+    @Override
+    protected IModel<List<String>> getLatestAlerts() {
+        return new ListModel<String>() {
+
+            private static final long serialVersionUID = 1232998477036705088L;
+
+            @Override
+            public List<String> getObject() {
+                return item.getTransformerClassNames();
+            }
+        };
+    }
+
+    @Override
+    protected AbstractLink getEventsLink(final String linkid) {
+        return new AjaxLink<String>(linkid) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                transformers.setItem(target, ItemTransformerWidget.this.item);
+                transformers.toggle(target, true);
+            }
+        };
+    }
+
+    @Override
+    protected Icon getIcon(final String iconid) {
+        return new Icon(
+                iconid, FontAwesomeIconTypeBuilder.on(FontAwesomeIconTypeBuilder.FontAwesomeGraphic.magic).build());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
index a4dec3d..6c4dd7b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.link.AbstractLink;
@@ -35,21 +35,21 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
 
     private static final long serialVersionUID = 7667120094526529934L;
 
-    private final MappingItemTO mapItem;
+    private final ItemTO item;
 
     private final JEXLTransformersTogglePanel transformers;
 
     public JEXLTransformerWidget(
             final String id,
-            final MappingItemTO mapItem,
+            final ItemTO item,
             final JEXLTransformersTogglePanel transformers) {
 
         super(id);
         setOutputMarkupId(true);
 
-        this.mapItem = mapItem;
+        this.item = item;
         this.transformers = transformers;
-        
+
         this.latestAlertsList.setVisible(false);
     }
 
@@ -62,11 +62,11 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
             @Override
             public List<String> getObject() {
                 List<String> result = new ArrayList<>();
-                if (StringUtils.isNotBlank(mapItem.getPropagationJEXLTransformer())) {
-                    result.add(mapItem.getPropagationJEXLTransformer());
+                if (StringUtils.isNotBlank(item.getPropagationJEXLTransformer())) {
+                    result.add(item.getPropagationJEXLTransformer());
                 }
-                if (StringUtils.isNotBlank(mapItem.getPullJEXLTransformer())) {
-                    result.add(mapItem.getPullJEXLTransformer());
+                if (StringUtils.isNotBlank(item.getPullJEXLTransformer())) {
+                    result.add(item.getPullJEXLTransformer());
                 }
                 return result;
             }
@@ -81,7 +81,7 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                transformers.setMappingItem(target, JEXLTransformerWidget.this.mapItem);
+                transformers.setItem(target, JEXLTransformerWidget.this.item);
                 transformers.toggle(target, true);
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
deleted file mode 100644
index 6e363dd..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.widgets;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
-import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconTypeBuilder;
-import java.util.List;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.markup.html.link.AbstractLink;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.util.ListModel;
-
-public class MappingItemTransformerWidget extends AlertWidget<String> {
-
-    private static final long serialVersionUID = 7667120094526529934L;
-
-    private final MappingItemTO mapItem;
-
-    private final MappingItemTransformersTogglePanel transformers;
-
-    public MappingItemTransformerWidget(
-            final String id,
-            final MappingItemTO mapItem,
-            final MappingItemTransformersTogglePanel transformers) {
-
-        super(id);
-        this.mapItem = mapItem;
-        this.transformers = transformers;
-        setOutputMarkupId(true);
-    }
-
-    @Override
-    protected IModel<List<String>> getLatestAlerts() {
-        return new ListModel<String>() {
-
-            private static final long serialVersionUID = 1232998477036705088L;
-
-            @Override
-            public List<String> getObject() {
-                return mapItem.getMappingItemTransformerClassNames();
-            }
-        };
-    }
-
-    @Override
-    protected AbstractLink getEventsLink(final String linkid) {
-        return new AjaxLink<String>(linkid) {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                transformers.setMappingItem(target, MappingItemTransformerWidget.this.mapItem);
-                transformers.toggle(target, true);
-            }
-        };
-    }
-
-    @Override
-    protected Icon getIcon(final String iconid) {
-        return new Icon(
-                iconid, FontAwesomeIconTypeBuilder.on(FontAwesomeIconTypeBuilder.FontAwesomeGraphic.magic).build());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
index 6872cde..5532f86 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
@@ -44,12 +44,12 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPan
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel;
 import org.apache.syncope.client.console.widgets.JEXLTransformerWidget;
-import org.apache.syncope.client.console.widgets.MappingItemTransformerWidget;
+import org.apache.syncope.client.console.widgets.ItemTransformerWidget;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -120,20 +120,18 @@ public abstract class AbstractMappingPanel extends Panel {
     /**
      * All mappings.
      */
-    protected final ListView<MappingItemTO> mappings;
+    protected final ListView<ItemTO> mappings;
 
     /**
      * Mapping container.
      */
     protected final WebMarkupContainer mappingContainer;
 
-    protected final IModel<List<MappingItemTO>> model;
-
     public AbstractMappingPanel(
             final String id,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ItemTransformersTogglePanel itemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers,
-            final IModel<List<MappingItemTO>> model,
+            final IModel<List<ItemTO>> model,
             final boolean addMappingBtnVisible,
             final boolean hidePurpose,
             final MappingPurpose defaultPurpose) {
@@ -141,8 +139,6 @@ public abstract class AbstractMappingPanel extends Panel {
         super(id);
         setOutputMarkupId(true);
 
-        this.model = model;
-
         mappingContainer = new WebMarkupContainer("mappingContainer");
         mappingContainer.setOutputMarkupId(true);
         add(mappingContainer);
@@ -173,10 +169,10 @@ public abstract class AbstractMappingPanel extends Panel {
 
         mappingContainer.add(Constants.getJEXLPopover(this, TooltipConfig.Placement.bottom));
 
-        Collections.sort(model.getObject(), new Comparator<MappingItemTO>() {
+        Collections.sort(model.getObject(), new Comparator<ItemTO>() {
 
             @Override
-            public int compare(final MappingItemTO left, final MappingItemTO right) {
+            public int compare(final ItemTO left, final ItemTO right) {
                 int compared;
                 if (left == null && right == null) {
                     compared = 0;
@@ -216,15 +212,15 @@ public abstract class AbstractMappingPanel extends Panel {
             }
         });
 
-        mappings = new ListView<MappingItemTO>("mappings", model.getObject()) {
+        mappings = new ListView<ItemTO>("mappings", model) {
 
             private static final long serialVersionUID = 4949588177564901031L;
 
             @Override
-            protected void populateItem(final ListItem<MappingItemTO> item) {
-                final MappingItemTO mapItem = item.getModelObject();
-                if (mapItem.getPurpose() == null) {
-                    mapItem.setPurpose(defaultPurpose);
+            protected void populateItem(final ListItem<ItemTO> item) {
+                final ItemTO itemTO = item.getModelObject();
+                if (itemTO.getPurpose() == null) {
+                    itemTO.setPurpose(defaultPurpose);
                 }
 
                 //--------------------------------
@@ -233,7 +229,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 AjaxTextFieldPanel intAttrName = new AjaxTextFieldPanel(
                         "intAttrName",
                         getString("intAttrName"),
-                        new PropertyModel<String>(mapItem, "intAttrName"),
+                        new PropertyModel<String>(itemTO, "intAttrName"),
                         false);
                 intAttrName.setChoices(Collections.<String>emptyList());
                 intAttrName.setRequired(true).hideLabel();
@@ -246,10 +242,10 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxTextFieldPanel extAttrName = new AjaxTextFieldPanel(
                         "extAttrName",
                         getString("extAttrName"),
-                        new PropertyModel<String>(mapItem, "extAttrName"));
+                        new PropertyModel<String>(itemTO, "extAttrName"));
                 extAttrName.setChoices(getExtAttrNames().getObject());
 
-                boolean required = !mapItem.isPassword();
+                boolean required = !itemTO.isPassword();
                 extAttrName.setRequired(required).hideLabel();
                 extAttrName.setEnabled(required);
                 item.add(extAttrName);
@@ -259,14 +255,14 @@ public abstract class AbstractMappingPanel extends Panel {
                 // JEXL transformers
                 // -------------------------------
                 item.add(new JEXLTransformerWidget(
-                        "jexlTransformers", mapItem, jexlTransformers).setRenderBodyOnly(true));
+                        "jexlTransformers", itemTO, jexlTransformers).setRenderBodyOnly(true));
                 // -------------------------------
 
                 //--------------------------------
                 // Mapping item transformers
                 // -------------------------------
-                item.add(new MappingItemTransformerWidget(
-                        "mappingItemTransformers", mapItem, mapItemTransformers).setRenderBodyOnly(true));
+                item.add(new ItemTransformerWidget(
+                        "itemTransformers", itemTO, itemTransformers).setRenderBodyOnly(true));
                 // -------------------------------
 
                 //--------------------------------
@@ -275,10 +271,10 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxTextFieldPanel mandatory = new AjaxTextFieldPanel(
                         "mandatoryCondition",
                         new ResourceModel("mandatoryCondition", "mandatoryCondition").getObject(),
-                        new PropertyModel<String>(mapItem, "mandatoryCondition"));
+                        new PropertyModel<String>(itemTO, "mandatoryCondition"));
                 mandatory.hideLabel();
                 mandatory.setChoices(Arrays.asList(new String[] { "true", "false" }));
-                mandatory.setEnabled(!mapItem.isConnObjectKey());
+                mandatory.setEnabled(!itemTO.isConnObjectKey());
                 item.add(mandatory);
                 // -------------------------------
 
@@ -288,7 +284,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxCheckBoxPanel connObjectKey = new AjaxCheckBoxPanel(
                         "connObjectKey",
                         new ResourceModel("connObjectKey", "connObjectKey").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "connObjectKey"), false);
+                        new PropertyModel<Boolean>(itemTO, "connObjectKey"), false);
                 connObjectKey.hideLabel();
                 item.add(connObjectKey);
                 // -------------------------------
@@ -299,7 +295,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel(
                         "password",
                         new ResourceModel("password", "password").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "password"), false);
+                        new PropertyModel<Boolean>(itemTO, "password"), false);
                 item.add(password.hideLabel());
                 // -------------------------------
 
@@ -310,7 +306,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 purpose.setOutputMarkupId(true);
 
                 final MappingPurposePanel purposeActions = new MappingPurposePanel(
-                        "purposeActions", new PropertyModel<MappingPurpose>(mapItem, "purpose"), purpose);
+                        "purposeActions", new PropertyModel<MappingPurpose>(itemTO, "purpose"), purpose);
                 purpose.add(purposeActions.setRenderBodyOnly(true));
                 item.add(purpose);
                 // -------------------------------
@@ -327,7 +323,7 @@ public abstract class AbstractMappingPanel extends Panel {
                     public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                         int index = -1;
                         for (int i = 0; i < model.getObject().size() && index == -1; i++) {
-                            if (mapItem.equals(model.getObject().get(i))) {
+                            if (itemTO.equals(model.getObject().get(i))) {
                                 index = i;
                             }
                         }
@@ -358,11 +354,11 @@ public abstract class AbstractMappingPanel extends Panel {
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
                         if (connObjectKey.getModelObject()) {
-                            mapItem.setMandatoryCondition("true");
+                            itemTO.setMandatoryCondition("true");
                             mandatory.setModelObject("true");
                             mandatory.setEnabled(false);
                         } else {
-                            mapItem.setMandatoryCondition("false");
+                            itemTO.setMandatoryCondition("false");
                             mandatory.setModelObject("false");
                             mandatory.setEnabled(true);
                         }
@@ -395,11 +391,11 @@ public abstract class AbstractMappingPanel extends Panel {
 
                     // Changes required by clone ....
                     extAttrName.setEnabled(true);
-                    if (mapItem.isPassword()) {
+                    if (itemTO.isPassword()) {
                         // re-enable if and only if cloned object mapping item was a password
                         intAttrName.setEnabled(true);
                     }
-                    mapItem.setPassword(false);
+                    itemTO.setPassword(false);
                 }
 
                 if (hidePurpose) {
@@ -417,7 +413,7 @@ public abstract class AbstractMappingPanel extends Panel {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                model.getObject().add(new MappingItemTO());
+                model.getObject().add(new ItemTO());
                 target.add(AbstractMappingPanel.this);
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 4ce8868..565c985 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -121,7 +121,7 @@ public class StatusPanel extends Panel {
         }
 
         statusBeans.add(syncope);
-        initialStatusBeanMap.put(syncope.getResourceName(), syncope);
+        initialStatusBeanMap.put(syncope.getResource(), syncope);
 
         for (Pair<ConnObjectTO, ConnObjectWrapper> pair : connObjects) {
             ConnObjectWrapper entry = pair.getRight();
@@ -164,14 +164,14 @@ public class StatusPanel extends Panel {
             @Override
             protected boolean statusCondition(final StatusBean bean) {
                 final Pair<ConnObjectTO, ConnObjectTO> pair
-                        = getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+                        = getConnObjectTO(bean.getKey(), bean.getResource(), connObjects);
 
                 return pair != null && pair.getRight() != null;
             }
 
             @Override
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
-                mlp.next(bean.getResourceName(), new RemoteAnyPanel(bean, connObjects), target);
+                mlp.next(bean.getResource(), new RemoteAnyPanel(bean, connObjects), target);
             }
         };
 
@@ -225,7 +225,7 @@ public class StatusPanel extends Panel {
 
         @Override
         protected final Pair<ConnObjectTO, ConnObjectTO> getConnObjectTO() {
-            return StatusPanel.this.getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+            return StatusPanel.this.getConnObjectTO(bean.getKey(), bean.getResource(), connObjects);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 6cf6023..44be252 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -39,7 +39,7 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
     private final UserRestClient userRestClient = new UserRestClient();
 
     /**
-     * Costructor to be used for templating only.
+     * Constructor to be used for templating only.
      *
      * @param anyTypeClasses any type classes.
      * @param formLayoutInfo form layout.

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
new file mode 100644
index 0000000..6e37955
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wizards.resources;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.panels.TogglePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
+
+    private static final long serialVersionUID = -3195479265440591519L;
+
+    private ItemTO item;
+
+    public ItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
+        super("outer", "itemTransformersTogglePanel", pageRef);
+
+        final LoadableDetachableModel<List<String>> model = new LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                // [!] this is required to disable changed with close button
+                return item == null
+                        ? Collections.<String>emptyList()
+                        : new ArrayList<>(item.getTransformerClassNames());
+            }
+        };
+
+        Form<?> form = new Form<>("form");
+        addInnerObject(form);
+
+        form.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).setRenderer(new IChoiceRenderer<String>() {
+
+            private static final long serialVersionUID = 3464376099975468136L;
+
+            private static final int MAX_LENGTH = 50;
+
+            @Override
+            public Object getDisplayValue(final String object) {
+                if (object.length() > MAX_LENGTH) {
+                    return "..." + object.substring(object.length() - MAX_LENGTH);
+                } else {
+                    return object;
+                }
+            }
+
+            @Override
+            public String getIdValue(final String object, final int index) {
+                return object;
+            }
+
+            @Override
+            public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
+                return id;
+            }
+        }).build(
+                "classes",
+                model,
+                new ListModel<>(new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getItemTransformers()))).
+                hideLabel().setEnabled(true).setOutputMarkupId(true));
+
+        form.add(new AjaxSubmitLink("submit", form) {
+
+            private static final long serialVersionUID = 5538299138211283825L;
+
+            @Override
+            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                toggle(target, false);
+
+                // [!] this is required to disable changed with close button
+                item.getTransformerClassNames().clear();
+                item.getTransformerClassNames().addAll(model.getObject());
+
+                target.add(container);
+            }
+
+        });
+    }
+
+    public ItemTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+        this.item = item;
+        setHeader(target, StringUtils.EMPTY);
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
index 759b708..da3847b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
@@ -22,7 +22,7 @@ import java.io.Serializable;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.panels.TogglePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
@@ -69,9 +69,9 @@ public class JEXLTransformersTogglePanel extends TogglePanel<Serializable> {
         });
     }
 
-    public JEXLTransformersTogglePanel setMappingItem(final AjaxRequestTarget target, final MappingItemTO mapItem) {
-        this.propagationJEXLTransformer.setNewModel(new PropertyModel<String>(mapItem, "propagationJEXLTransformer"));
-        this.pullJEXLTransformer.setNewModel(new PropertyModel<String>(mapItem, "pullJEXLTransformer"));
+    public JEXLTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+        this.propagationJEXLTransformer.setNewModel(new PropertyModel<String>(item, "propagationJEXLTransformer"));
+        this.pullJEXLTransformer.setNewModel(new PropertyModel<String>(item, "pullJEXLTransformer"));
         setHeader(target, StringUtils.EMPTY);
         return this;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
deleted file mode 100644
index 3298d20..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.wizards.resources;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.panels.TogglePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.IChoiceRenderer;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.util.ListModel;
-
-public class MappingItemTransformersTogglePanel extends TogglePanel<Serializable> {
-
-    private static final long serialVersionUID = -3195479265440591519L;
-
-    private MappingItemTO mapItem;
-
-    public MappingItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
-        super("outer", "mappingItemTransformersTogglePanel", pageRef);
-
-        final LoadableDetachableModel<List<String>> model = new LoadableDetachableModel<List<String>>() {
-
-            private static final long serialVersionUID = 5275935387613157437L;
-
-            @Override
-            protected List<String> load() {
-                // [!] this is required to disable changed with close button
-                return mapItem == null
-                        ? Collections.<String>emptyList()
-                        : new ArrayList<>(mapItem.getMappingItemTransformerClassNames());
-            }
-        };
-
-        Form<?> form = new Form<>("form");
-        addInnerObject(form);
-
-        form.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).setRenderer(new IChoiceRenderer<String>() {
-
-            private static final long serialVersionUID = 3464376099975468136L;
-
-            private static final int MAX_LENGTH = 50;
-
-            @Override
-            public Object getDisplayValue(final String object) {
-                if (object.length() > MAX_LENGTH) {
-                    return "..." + object.substring(object.length() - MAX_LENGTH);
-                } else {
-                    return object;
-                }
-            }
-
-            @Override
-            public String getIdValue(final String object, final int index) {
-                return object;
-            }
-
-            @Override
-            public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
-                return id;
-            }
-        }).build(
-                "classes",
-                model,
-                new ListModel<>(
-                        new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getMappingItemTransformers()))).
-                hideLabel().setEnabled(true).setOutputMarkupId(true));
-
-        form.add(new AjaxSubmitLink("submit", form) {
-
-            private static final long serialVersionUID = 5538299138211283825L;
-
-            @Override
-            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                toggle(target, false);
-
-                // [!] this is required to disable changed with close button
-                mapItem.getMappingItemTransformerClassNames().clear();
-                mapItem.getMappingItemTransformerClassNames().addAll(model.getObject());
-
-                target.add(container);
-            }
-
-        });
-    }
-
-    public MappingItemTransformersTogglePanel setMappingItem(
-            final AjaxRequestTarget target, final MappingItemTO mapItem) {
-
-        this.mapItem = mapItem;
-        setHeader(target, StringUtils.EMPTY);
-        return this;
-    }
-}


[09/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
index 9666804..b2907c4 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.api.pushpull;
 
 import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
@@ -132,19 +131,18 @@ public interface PullActions extends ProvisioningActions {
      * The entity is updated upon pull in case of the matching rule
      * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
      *
-     * @param <M> concrete any object
      * @param <P> any object modifications
      * @param profile profile of the pull being executed.
      * @param delta retrieved pull information
-     * @param any any object
+     * @param entityTO entity
      * @param anyPatch modification
      * @return pull information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure.
      */
-    <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+    <P extends AnyPatch> SyncDelta beforeUpdate(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            M any,
+            EntityTO entityTO,
             P anyPatch)
             throws JobExecutionException;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index 38c895e..54ada98 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -23,55 +23,60 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 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.GroupableRelatableTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.spring.security.Encryptor;
-import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 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.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.GroupableRelatable;
 import org.apache.syncope.core.persistence.api.entity.Membership;
+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.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 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.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+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.DerAttrHandler;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.identityconnectors.framework.common.FrameworkUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -82,7 +87,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.apache.syncope.common.lib.to.GroupableRelatableTO;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Component
 public class MappingManagerImpl implements MappingManager {
@@ -110,6 +115,9 @@ public class MappingManagerImpl implements MappingManager {
     private GroupDAO groupDAO;
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private DerAttrHandler derAttrHandler;
 
     @Autowired
@@ -145,7 +153,7 @@ public class MappingManagerImpl implements MappingManager {
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
 
-        for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(provision)) {
+        for (MappingItem mapItem : MappingUtils.getPropagationItems(provision)) {
             LOG.debug("Processing expression '{}'", mapItem.getIntAttrName());
 
             try {
@@ -164,7 +172,7 @@ public class MappingManagerImpl implements MappingManager {
                             attributes.remove(alreadyAdded);
 
                             Set<Object> values = new HashSet<>();
-                            if (alreadyAdded.getValue() != null && !alreadyAdded.getValue().isEmpty()) {
+                            if (CollectionUtils.isNotEmpty(alreadyAdded.getValue())) {
                                 values.addAll(alreadyAdded.getValue());
                             }
 
@@ -198,7 +206,75 @@ public class MappingManagerImpl implements MappingManager {
             }
         }
 
-        return new ImmutablePair<>(connObjectKey, attributes);
+        return Pair.of(connObjectKey, attributes);
+    }
+
+    private String getIntValue(final Realm realm, final OrgUnitItem orgUnitItem) {
+        String value = null;
+        switch (orgUnitItem.getIntAttrName()) {
+            case "key":
+                value = realm.getKey();
+                break;
+
+            case "name":
+                value = realm.getName();
+                break;
+
+            case "fullpath":
+                value = realm.getFullPath();
+                break;
+
+            default:
+        }
+
+        return value;
+    }
+
+    @Override
+    public Pair<String, Set<Attribute>> prepareAttrs(final Realm realm, final OrgUnit orgUnit) {
+        LOG.debug("Preparing resource attributes for {} with orgUnit {}", realm, orgUnit);
+
+        Set<Attribute> attributes = new HashSet<>();
+        String connObjectKey = null;
+
+        for (OrgUnitItem orgUnitItem : MappingUtils.getPropagationItems(orgUnit)) {
+            LOG.debug("Processing expression '{}'", orgUnitItem.getIntAttrName());
+
+            String value = getIntValue(realm, orgUnitItem);
+
+            if (orgUnitItem.isConnObjectKey()) {
+                connObjectKey = value;
+            }
+
+            Attribute alreadyAdded = AttributeUtil.find(orgUnitItem.getExtAttrName(), attributes);
+            if (alreadyAdded == null) {
+                if (value == null) {
+                    attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName()));
+                } else {
+                    attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), value));
+                }
+            } else if (value != null) {
+                attributes.remove(alreadyAdded);
+
+                Set<Object> values = new HashSet<>();
+                if (CollectionUtils.isNotEmpty(alreadyAdded.getValue())) {
+                    values.addAll(alreadyAdded.getValue());
+                }
+                values.add(value);
+
+                attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), values));
+            }
+        }
+
+        Attribute connObjectKeyExtAttr =
+                AttributeUtil.find(orgUnit.getConnObjectKeyItem().getExtAttrName(), attributes);
+        if (connObjectKeyExtAttr != null) {
+            attributes.remove(connObjectKeyExtAttr);
+            attributes.add(AttributeBuilder.build(orgUnit.getConnObjectKeyItem().getExtAttrName(), connObjectKey));
+        }
+        attributes.add(MappingUtils.evaluateNAME(realm, orgUnit, connObjectKey));
+
+        return Pair.of(connObjectKey, attributes);
     }
 
     /**
@@ -263,7 +339,7 @@ public class MappingManagerImpl implements MappingManager {
             }
 
             if (mapItem.isConnObjectKey()) {
-                result = new ImmutablePair<>(objValues.isEmpty() ? null : objValues.iterator().next().toString(), null);
+                result = Pair.of(objValues.isEmpty() ? null : objValues.iterator().next().toString(), null);
             } else if (mapItem.isPassword() && any instanceof User) {
                 String passwordAttrValue = password;
                 if (StringUtils.isBlank(passwordAttrValue)) {
@@ -286,15 +362,12 @@ public class MappingManagerImpl implements MappingManager {
                 if (passwordAttrValue == null) {
                     result = null;
                 } else {
-                    result = new ImmutablePair<>(
-                            null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
+                    result = Pair.of(null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
                 }
             } else if (schema != null && schema.isMultivalue()) {
-                result = new ImmutablePair<>(
-                        null, AttributeBuilder.build(mapItem.getExtAttrName(), objValues));
+                result = Pair.of(null, AttributeBuilder.build(mapItem.getExtAttrName(), objValues));
             } else {
-                result = new ImmutablePair<>(
-                        null, objValues.isEmpty()
+                result = Pair.of(null, objValues.isEmpty()
                         ? AttributeBuilder.build(mapItem.getExtAttrName())
                         : AttributeBuilder.build(mapItem.getExtAttrName(), objValues.iterator().next()));
             }
@@ -484,7 +557,7 @@ public class MappingManagerImpl implements MappingManager {
 
         List<PlainAttrValue> transformed = values;
         if (transform) {
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mapItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem)) {
                 transformed = transformer.beforePropagation(mapItem, any, transformed);
             }
             LOG.debug("Transformed values: {}", values);
@@ -519,13 +592,21 @@ public class MappingManagerImpl implements MappingManager {
 
     @Transactional(readOnly = true)
     @Override
+    public String getConnObjectKeyValue(final Realm realm, final OrgUnit orgUnit) {
+        OrgUnitItem orgUnitItem = orgUnit.getConnObjectKeyItem();
+
+        return getIntValue(realm, orgUnitItem);
+    }
+
+    @Transactional(readOnly = true)
+    @Override
     public void setIntValues(
             final MappingItem mapItem, final Attribute attr, final AnyTO anyTO, final AnyUtils anyUtils) {
 
         List<Object> values = null;
         if (attr != null) {
             values = attr.getValue();
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mapItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem)) {
                 values = transformer.beforePull(mapItem, anyTO, values);
             }
         }
@@ -679,4 +760,36 @@ public class MappingManagerImpl implements MappingManager {
             }
         }
     }
+
+    @Override
+    public void setIntValues(final OrgUnitItem orgUnitItem, final Attribute attr, final RealmTO realmTO) {
+        List<Object> values = null;
+        if (attr != null) {
+            values = attr.getValue();
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(orgUnitItem)) {
+                values = transformer.beforePull(orgUnitItem, realmTO, values);
+            }
+        }
+
+        if (values != null && !values.isEmpty() && values.get(0) != null) {
+            switch (orgUnitItem.getIntAttrName()) {
+                case "name":
+                    realmTO.setName(values.get(0).toString());
+                    break;
+
+                case "fullpath":
+                    String parentFullPath = StringUtils.substringBeforeLast(values.get(0).toString(), "/");
+                    Realm parent = realmDAO.findByFullPath(parentFullPath);
+                    if (parent == null) {
+                        LOG.warn("Could not find Realm with path {}, ignoring", parentFullPath);
+                    } else {
+                        realmTO.setParent(parent.getFullPath());
+                    }
+                    break;
+
+                default:
+            }
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/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 b25712b..108b530 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
@@ -226,7 +226,7 @@ abstract class AbstractAnyDataBinder {
     private List<String> evaluateMandatoryCondition(final Provision provision, final Any<?> any) {
         List<String> missingAttrNames = new ArrayList<>();
 
-        for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(provision)) {
+        for (MappingItem mapItem : MappingUtils.getPropagationItems(provision)) {
             IntAttrName intAttrName =
                     intAttrNameParser.parse(mapItem.getIntAttrName(), provision.getAnyType().getKind());
             if (intAttrName.getSchemaType() != null) {
@@ -346,7 +346,7 @@ abstract class AbstractAnyDataBinder {
         }
 
         for (ExternalResource resource : resources) {
-            for (MappingItem item : MappingUtils.getPropagationMappingItems(resource.getProvision(any.getType()))) {
+            for (MappingItem item : MappingUtils.getPropagationItems(resource.getProvision(any.getType()))) {
                 if (schema.getKey().equals(item.getIntAttrName())) {
                     propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
new file mode 100644
index 0000000..230962a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultItemTransformer.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Default (empty) implementation of {@link ItemTransformer}.
+ */
+@Transactional(readOnly = true)
+public class DefaultItemTransformer implements ItemTransformer {
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item, final Entity entity, final List<PlainAttrValue> values) {
+
+        return values;
+    }
+
+    @Override
+    public List<Object> beforePull(final Item item, final EntityTO entityTO, final List<Object> values) {
+        return values;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
deleted file mode 100644
index 37a471c..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/DefaultMappingItemTransformer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Default (empty) implementation of {@link MappingItemTransformer}.
- */
-public class DefaultMappingItemTransformer implements MappingItemTransformer {
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        return values;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        return values;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
new file mode 100644
index 0000000..ae31618
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
+
+public class JEXLItemTransformerImpl extends DefaultItemTransformer implements JEXLItemTransformer {
+
+    private String propagationJEXL;
+
+    private String pullJEXL;
+
+    @Override
+    public void setPropagationJEXL(final String propagationJEXL) {
+        this.propagationJEXL = propagationJEXL;
+    }
+
+    @Override
+    public void setPullJEXL(final String pullJEXL) {
+        this.pullJEXL = pullJEXL;
+    }
+
+    @Override
+    public List<PlainAttrValue> beforePropagation(
+            final Item item,
+            final Entity entity,
+            final List<PlainAttrValue> values) {
+
+        if (StringUtils.isNotBlank(propagationJEXL) && values != null) {
+            for (PlainAttrValue value : values) {
+                JexlContext jexlContext = new MapContext();
+                if (entity != null) {
+                    JexlUtils.addFieldsToContext(entity, jexlContext);
+                    if (entity instanceof Any) {
+                        JexlUtils.addPlainAttrsToContext(((Any<?>) entity).getPlainAttrs(), jexlContext);
+                        JexlUtils.addDerAttrsToContext(((Any<?>) entity), jexlContext);
+                    }
+                }
+                jexlContext.set("value", value.getValueAsString());
+
+                value.setStringValue(JexlUtils.evaluate(propagationJEXL, jexlContext));
+            }
+
+            return values;
+        }
+
+        return super.beforePropagation(item, entity, values);
+    }
+
+    @Override
+    public List<Object> beforePull(
+            final Item item,
+            final EntityTO entityTO,
+            final List<Object> values) {
+
+        if (StringUtils.isNotBlank(pullJEXL) && values != null) {
+            List<Object> newValues = new ArrayList<>(values.size());
+            for (Object value : values) {
+                JexlContext jexlContext = new MapContext();
+                jexlContext.set("value", value);
+                if (entityTO instanceof AnyTO) {
+                    newValues.add(JexlUtils.evaluate(pullJEXL, (AnyTO) entityTO, jexlContext));
+                } else {
+                    newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
+                }
+            }
+
+            return newValues;
+        }
+
+        return super.beforePull(item, entityTO, values);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
deleted file mode 100644
index 07618aa..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLMappingItemTransformerImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.JEXLMappingItemTransformer;
-import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
-
-public class JEXLMappingItemTransformerImpl
-        extends DefaultMappingItemTransformer implements JEXLMappingItemTransformer {
-
-    private String propagationJEXL;
-
-    private String pullJEXL;
-
-    @Override
-    public void setPropagationJEXL(final String propagationJEXL) {
-        this.propagationJEXL = propagationJEXL;
-    }
-
-    @Override
-    public void setPullJEXL(final String pullJEXL) {
-        this.pullJEXL = pullJEXL;
-    }
-
-    @Override
-    public List<PlainAttrValue> beforePropagation(
-            final MappingItem mappingItem,
-            final Any<?> any,
-            final List<PlainAttrValue> values) {
-
-        if (StringUtils.isNotBlank(propagationJEXL) && values != null) {
-            for (PlainAttrValue value : values) {
-                JexlContext jexlContext = new MapContext();
-                if (any != null) {
-                    JexlUtils.addFieldsToContext(any, jexlContext);
-                    JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
-                    JexlUtils.addDerAttrsToContext(any, jexlContext);
-                }
-                jexlContext.set("value", value.getValueAsString());
-
-                value.setStringValue(JexlUtils.evaluate(propagationJEXL, jexlContext));
-            }
-
-            return values;
-        }
-
-        return super.beforePropagation(mappingItem, any, values);
-    }
-
-    @Override
-    public List<Object> beforePull(
-            final MappingItem mappingItem,
-            final AnyTO anyTO,
-            final List<Object> values) {
-
-        if (StringUtils.isNotBlank(pullJEXL) && values != null) {
-            List<Object> newValues = new ArrayList<>(values.size());
-            for (Object value : values) {
-                JexlContext jexlContext = new MapContext();
-                jexlContext.set("value", value);
-                if (anyTO == null) {
-                    newValues.add(JexlUtils.evaluate(pullJEXL, jexlContext));
-                } else {
-                    newValues.add(JexlUtils.evaluate(pullJEXL, anyTO, jexlContext));
-                }
-            }
-
-            return newValues;
-        }
-
-        return super.beforePull(mappingItem, anyTO, values);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/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 e6293cf..ba6da63 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
@@ -27,7 +27,8 @@ import org.apache.commons.collections4.IteratorUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemContainerTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
@@ -58,7 +59,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResourceHistoryConf;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
@@ -76,7 +79,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
     private static final Logger LOG = LoggerFactory.getLogger(ResourceDataBinder.class);
 
-    private static final String[] MAPPINGITEM_IGNORE_PROPERTIES = { "key", "mapping" };
+    private static final String[] ITEM_IGNORE_PROPERTIES = { "key", "mapping" };
 
     @Autowired
     private AnyTypeDAO anyTypeDAO;
@@ -126,7 +129,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             List<ExternalResourceHistoryConf> history = resourceHistoryConfDAO.findByEntity(resource);
             long maxHistorySize = confDAO.find("resource.conf.history.size", "10").getValues().get(0).getLongValue();
             if (maxHistorySize < history.size()) {
-            // always remove the last item since history was obtained  by a query with ORDER BY creation DESC
+                // always remove the last item since history was obtained  by a query with ORDER BY creation DESC
                 for (int i = 0; i < history.size() - maxHistorySize; i++) {
                     resourceHistoryConfDAO.delete(history.get(history.size() - 1).getKey());
                 }
@@ -275,19 +278,60 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             }
             orgUnit.setObjectClass(new ObjectClass(orgUnitTO.getObjectClass()));
 
-            if (orgUnitTO.getExtAttrName() == null) {
-                SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
-                sce.getElements().add("Null extAttrName");
-                throw sce;
-            }
-            orgUnit.setExtAttrName(orgUnitTO.getExtAttrName());
-
             if (orgUnitTO.getConnObjectLink() == null) {
                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
                 sce.getElements().add("Null connObjectLink");
                 throw sce;
             }
             orgUnit.setConnObjectLink(orgUnitTO.getConnObjectLink());
+
+            SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+            SyncopeClientException invalidMapping = SyncopeClientException.build(
+                    ClientExceptionType.InvalidMapping);
+            SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
+                    ClientExceptionType.RequiredValuesMissing);
+
+            orgUnit.getItems().clear();
+            for (ItemTO itemTO : orgUnitTO.getItems()) {
+                if (itemTO == null) {
+                    LOG.error("Null {}", ItemTO.class.getSimpleName());
+                    invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
+                } else if (itemTO.getIntAttrName() == null) {
+                    requiredValuesMissing.getElements().add("intAttrName");
+                    scce.addException(requiredValuesMissing);
+                } else {
+                    if (!"name".equals(itemTO.getIntAttrName()) && !"fullpath".equals(itemTO.getIntAttrName())) {
+                        LOG.error("Only 'name' and 'fullpath' are supported for Realms");
+                        invalidMapping.getElements().add("Only 'name' and 'fullpath' are supported for Realms");
+                    } else {
+                        // no mandatory condition implies mandatory condition false
+                        if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
+                                ? "false" : itemTO.getMandatoryCondition())) {
+
+                            SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
+                                    ClientExceptionType.InvalidValues);
+                            invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
+                            scce.addException(invalidMandatoryCondition);
+                        }
+
+                        OrgUnitItem item = entityFactory.newEntity(OrgUnitItem.class);
+                        BeanUtils.copyProperties(itemTO, item, ITEM_IGNORE_PROPERTIES);
+                        item.setOrgUnit(orgUnit);
+                        if (item.isConnObjectKey()) {
+                            orgUnit.setConnObjectKeyItem(item);
+                        } else {
+                            orgUnit.add(item);
+                        }
+
+                    }
+                }
+            }
+            if (!invalidMapping.getElements().isEmpty()) {
+                scce.addException(invalidMapping);
+            }
+            if (scce.hasExceptions()) {
+                throw scce;
+            }
         }
 
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
@@ -328,10 +372,10 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
                 ClientExceptionType.RequiredValuesMissing);
 
-        for (MappingItemTO itemTO : mappingTO.getItems()) {
+        for (ItemTO itemTO : mappingTO.getItems()) {
             if (itemTO == null) {
-                LOG.error("Null {}", MappingItemTO.class.getSimpleName());
-                invalidMapping.getElements().add("Null " + MappingItemTO.class.getSimpleName());
+                LOG.error("Null {}", ItemTO.class.getSimpleName());
+                invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
             } else if (itemTO.getIntAttrName() == null) {
                 requiredValuesMissing.getElements().add("intAttrName");
                 scce.addException(requiredValuesMissing);
@@ -377,7 +421,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
                         }
 
                         MappingItem item = entityFactory.newEntity(MappingItem.class);
-                        BeanUtils.copyProperties(itemTO, item, MAPPINGITEM_IGNORE_PROPERTIES);
+                        BeanUtils.copyProperties(itemTO, item, ITEM_IGNORE_PROPERTIES);
                         item.setMapping(mapping);
                         if (item.isConnObjectKey()) {
                             if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) {
@@ -442,18 +486,16 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         }
     }
 
-    private void populateMappingTO(final Mapping mapping, final MappingTO mappingTO) {
-        mappingTO.setConnObjectLink(mapping.getConnObjectLink());
-
-        for (MappingItem item : mapping.getItems()) {
-            MappingItemTO itemTO = new MappingItemTO();
+    private void populateItems(final List<? extends Item> items, final ItemContainerTO containerTO) {
+        for (Item item : items) {
+            ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
-            BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+            BeanUtils.copyProperties(item, itemTO, ITEM_IGNORE_PROPERTIES);
 
             if (itemTO.isConnObjectKey()) {
-                mappingTO.setConnObjectKeyItem(itemTO);
+                containerTO.setConnObjectKeyItem(itemTO);
             } else {
-                mappingTO.add(itemTO);
+                containerTO.add(itemTO);
             }
         }
     }
@@ -484,7 +526,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             if (provision.getMapping() != null) {
                 MappingTO mappingTO = new MappingTO();
                 provisionTO.setMapping(mappingTO);
-                populateMappingTO(provision.getMapping(), mappingTO);
+                mappingTO.setConnObjectLink(provision.getMapping().getConnObjectLink());
+                populateItems(provision.getMapping().getItems(), mappingTO);
             }
 
             for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
@@ -492,9 +535,9 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
                 MappingItem linkingMappingItem = virSchema.asLinkingMappingItem();
 
-                MappingItemTO itemTO = new MappingItemTO();
+                ItemTO itemTO = new ItemTO();
                 itemTO.setKey(linkingMappingItem.getKey());
-                BeanUtils.copyProperties(linkingMappingItem, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+                BeanUtils.copyProperties(linkingMappingItem, itemTO, ITEM_IGNORE_PROPERTIES);
 
                 provisionTO.getMapping().getLinkingItems().add(itemTO);
             }
@@ -509,8 +552,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             orgUnitTO.setKey(orgUnit.getKey());
             orgUnitTO.setObjectClass(orgUnit.getObjectClass().getObjectClassValue());
             orgUnitTO.setSyncToken(orgUnit.getSerializedSyncToken());
-            orgUnitTO.setExtAttrName(orgUnit.getExtAttrName());
             orgUnitTO.setConnObjectLink(orgUnit.getConnObjectLink());
+            populateItems(orgUnit.getItems(), orgUnitTO);
 
             resourceTO.setOrgUnit(orgUnitTO);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/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 a14ba2f..b24c85c 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
@@ -51,9 +51,7 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
@@ -69,15 +67,12 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationException
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
 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.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder;
 import org.identityconnectors.framework.common.objects.Name;
 import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
 import org.identityconnectors.framework.common.objects.Uid;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -120,12 +115,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     protected GroupDAO groupDAO;
 
     /**
-     * Realm DAO.
-     */
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    /**
      * Task DAO.
      */
     @Autowired
@@ -396,7 +385,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                     ? null
                     : orgUnit == null
                             ? getRemoteObject(task, connector, provision, false)
-                            : getRemoteObject(task, connector, orgUnit);
+                            : getRemoteObject(task, connector, orgUnit, false);
 
             for (PropagationActions action : actions) {
                 action.before(task, beforeObj);
@@ -463,7 +452,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                             ? null
                             : orgUnit == null
                                     ? getRemoteObject(task, connector, provision, true)
-                                    : getRemoteObject(task, connector, orgUnit);
+                                    : getRemoteObject(task, connector, orgUnit, true);
                 } catch (Exception ignore) {
                     // ignore exception
                     LOG.error("Error retrieving after object", ignore);
@@ -621,7 +610,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
                     new Uid(connObjectKey),
                     MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
-                            MappingUtils.getPropagationMappingItems(provision).iterator(),
+                            MappingUtils.getPropagationItems(provision).iterator(),
                             linkingMappingItems.iterator())));
 
             for (MappingItem item : linkingMappingItems) {
@@ -650,37 +639,31 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
      * @param connector connector facade proxy.
      * @param task current propagation task.
      * @param orgUnit orgUnit
+     * @param latest 'FALSE' to retrieve object using old connObjectKey if not null.
      * @return remote connector object.
      */
     protected ConnectorObject getRemoteObject(
             final PropagationTask task,
             final Connector connector,
-            final OrgUnit orgUnit) {
+            final OrgUnit orgUnit,
+            final boolean latest) {
 
-        Realm realm = realmDAO.find(task.getEntityKey());
-        if (realm == null) {
-            return null;
-        }
+        String connObjectKey = latest || task.getOldConnObjectKey() == null
+                ? task.getConnObjectKey()
+                : task.getOldConnObjectKey();
 
-        final ConnectorObject[] obj = new ConnectorObject[1];
+        ConnectorObject obj = null;
         try {
-            connector.search(new ObjectClass(task.getObjectClassName()),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realm.getName())),
-                    new ResultsHandler() {
-
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
+            obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
+                    new Uid(connObjectKey),
+                    MappingUtils.buildOperationOptions(MappingUtils.getPropagationItems(orgUnit).iterator()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", task.getConnObjectKey(), ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
 
-        return obj[0];
+        return obj;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/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 f1ec799..c826f6b 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
@@ -28,8 +28,6 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.StringPatchItem;
@@ -68,7 +66,6 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -204,8 +201,8 @@ public class PropagationManagerImpl implements PropagationManager {
         return getUpdateTasks(
                 userDAO.authFind(wfResult.getResult().getKey().getKey()),
                 wfResult.getResult().getKey().getPassword() == null
-                        ? null
-                        : wfResult.getResult().getKey().getPassword().getValue(),
+                ? null
+                : wfResult.getResult().getKey().getPassword().getValue(),
                 changePwd,
                 wfResult.getResult().getValue(),
                 wfResult.getPropByRes(),
@@ -381,9 +378,9 @@ public class PropagationManagerImpl implements PropagationManager {
         for (Map.Entry<String, ResourceOperation> entry : propByRes.asMap().entrySet()) {
             ExternalResource resource = resourceDAO.find(entry.getKey());
             Provision provision = resource == null ? null : resource.getProvision(any.getType());
-            List<MappingItem> mappingItems = provision == null
+            List<? extends MappingItem> mappingItems = provision == null
                     ? Collections.<MappingItem>emptyList()
-                    : MappingUtils.getPropagationMappingItems(provision);
+                    : MappingUtils.getPropagationItems(provision);
 
             if (resource == null) {
                 LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -484,28 +481,11 @@ public class PropagationManagerImpl implements PropagationManager {
                 task.setObjectClassName(orgUnit.getObjectClass().getObjectClassValue());
                 task.setEntityKey(realm.getKey());
                 task.setOperation(entry.getValue());
+                task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
-                Set<Attribute> preparedAttrs = new HashSet<>();
-                preparedAttrs.add(AttributeBuilder.build(orgUnit.getExtAttrName(), realm.getName()));
-
-                JexlContext jexlContext = new MapContext();
-                JexlUtils.addFieldsToContext(realm, jexlContext);
-                String evalConnObjectLink = JexlUtils.evaluate(orgUnit.getConnObjectLink(), jexlContext);
-                if (StringUtils.isBlank(evalConnObjectLink)) {
-                    // add connObjectKey as __NAME__ attribute ...
-                    LOG.debug("Add connObjectKey [{}] as __NAME__", realm.getName());
-                    preparedAttrs.add(new Name(realm.getName()));
-                } else {
-                    LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
-                    preparedAttrs.add(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");
-                }
-
-                task.setConnObjectKey(realm.getName());
-
-                task.setAttributes(preparedAttrs);
+                Pair<String, Set<Attribute>> preparedAttrs = mappingManager.prepareAttrs(realm, orgUnit);
+                task.setConnObjectKey(preparedAttrs.getKey());
+                task.setAttributes(preparedAttrs.getValue());
 
                 tasks.add(task);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
index af8466c..1e93b92 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java
@@ -178,7 +178,6 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
         }
 
         AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
         anyTO.getResources().add(profile.getTask().getResource().getKey());
 
         ProvisioningReport result = new ProvisioningReport();
@@ -324,9 +323,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                 result.setName(getName(before));
             }
 
-            Result resultStatus;
-            Object output;
             if (!profile.isDryRun()) {
+                Result resultStatus;
+                Object output;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -395,16 +395,13 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to update {}", anys);
+        LOG.debug("About to deprovision {}", anys);
 
-        final List<ProvisioningReport> updResults = new ArrayList<>();
+        final List<ProvisioningReport> results = new ArrayList<>();
 
         for (String key : anys) {
             LOG.debug("About to unassign resource {}", key);
 
-            Object output;
-            Result resultStatus;
-
             ProvisioningReport result = new ProvisioningReport();
             result.setOperation(ResourceOperation.DELETE);
             result.setAnyType(provision.getAnyType().getKey());
@@ -419,6 +416,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
 
             if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -487,10 +487,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                         ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
                         : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
             }
-            updResults.add(result);
+            results.add(result);
         }
 
-        return updResults;
+        return results;
     }
 
     protected List<ProvisioningReport> link(
@@ -510,14 +510,11 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
 
         LOG.debug("About to update {}", anys);
 
-        final List<ProvisioningReport> updResults = new ArrayList<>();
+        final List<ProvisioningReport> results = new ArrayList<>();
 
         for (String key : anys) {
             LOG.debug("About to unassign resource {}", key);
 
-            Object output;
-            Result resultStatus;
-
             ProvisioningReport result = new ProvisioningReport();
             result.setOperation(ResourceOperation.NONE);
             result.setAnyType(provision.getAnyType().getKey());
@@ -532,6 +529,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
 
             if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
+
                 if (before == null) {
                     resultStatus = Result.FAILURE;
                     output = null;
@@ -585,10 +585,10 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                         ? MatchingRule.toEventName(MatchingRule.UNLINK)
                         : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
             }
-            updResults.add(result);
+            results.add(result);
         }
 
-        return updResults;
+        return results;
     }
 
     protected List<ProvisioningReport> delete(
@@ -605,7 +605,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
 
         LOG.debug("About to delete {}", anys);
 
-        List<ProvisioningReport> delResults = new ArrayList<>();
+        List<ProvisioningReport> results = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
         for (String key : anys) {
@@ -648,7 +648,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
                     finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
                 }
 
-                delResults.add(result);
+                results.add(result);
             } catch (NotFoundException e) {
                 LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
             } catch (DelegatedAdministrationException e) {
@@ -658,7 +658,7 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
             }
         }
 
-        return delResults;
+        return results;
     }
 
     protected ProvisioningReport ignore(

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
index cd2aaf3..d5b2093 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java
@@ -23,7 +23,6 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.PasswordPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -76,10 +75,10 @@ public class DBPasswordPullActions extends DefaultPullActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         if (anyPatch instanceof UserPatch) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
index a75ff8b..9344835 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPullActions.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.java.pushpull;
 
 import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
@@ -38,10 +37,10 @@ public abstract class DefaultPullActions implements PullActions {
     }
 
     @Override
-    public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+    public <P extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final P anyMod) throws JobExecutionException {
 
         return delta;

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
index 967b27c..f11a20e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.java.pushpull;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.PasswordPatch;
 import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -70,10 +69,10 @@ public class LDAPPasswordPullActions extends DefaultPullActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+    public <M extends AnyPatch> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final A any,
+            final EntityTO entityTO,
             final M anyPatch) throws JobExecutionException {
 
         if (anyPatch instanceof UserPatch) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
index 33a9634..81bfd70 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PlainAttrsPullCorrelationRule.java
@@ -27,11 +27,11 @@ import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
 
@@ -47,7 +47,7 @@ public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
     @Override
     public SearchCond getSearchCond(final ConnectorObject connObj) {
         Map<String, MappingItem> mappingItems = new HashMap<>();
-        for (MappingItem item : MappingUtils.getPullMappingItems(provision)) {
+        for (MappingItem item : MappingUtils.getPullItems(provision)) {
             mappingItems.put(item.getIntAttrName(), item);
         }
 
@@ -65,7 +65,7 @@ public class PlainAttrsPullCorrelationRule implements PullCorrelationRule {
             }
 
             List<Object> values = attr.getValue();
-            for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(mappingItem)) {
+            for (ItemTransformer transformer : MappingUtils.getItemTransformers(mappingItem)) {
                 values = transformer.beforePull(mappingItem, null, values);
             }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index fa7807e..3520db0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -151,10 +151,10 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
         // First OrgUnits...
         if (pullTask.getResource().getOrgUnit() != null) {
             OrgUnit orgUnit = pullTask.getResource().getOrgUnit();
-            OperationOptions options = MappingUtils.buildOperationOptions(orgUnit);
+            OperationOptions options = MappingUtils.buildOperationOptions(
+                    MappingUtils.getPullItems(orgUnit).iterator());
 
-            SyncopePullResultHandler rhandler =
-                    (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
+            SyncopePullResultHandler rhandler = (SyncopePullResultHandler) ApplicationContextProvider.getBeanFactory().
                     createBean(RealmPullResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
             rhandler.setProfile(profile);
             rhandler.setPullExecutor(this);
@@ -181,8 +181,8 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
                     case FILTERED_RECONCILIATION:
                         ReconciliationFilterBuilder filterBuilder =
                                 (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
-                                createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
-                                        AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+                                        createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
+                                                AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
                         connector.filteredReconciliation(orgUnit.getObjectClass(),
                                 filterBuilder,
                                 rhandler,
@@ -265,8 +265,9 @@ public class PullJobDelegate extends AbstractProvisioningJobDelegate<PullTask> i
                         case FILTERED_RECONCILIATION:
                             ReconciliationFilterBuilder filterBuilder =
                                     (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
-                                    createBean(Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
-                                            AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+                                            createBean(
+                                                    Class.forName(pullTask.getReconciliationFilterBuilderClassName()),
+                                                    AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
                             connector.filteredReconciliation(provision.getObjectClass(),
                                     filterBuilder,
                                     handler,

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
index e73517c..819c5f3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.pushpull;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.policy.PullPolicySpec;
@@ -31,6 +32,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -38,17 +40,19 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.api.IntAttrName;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -62,7 +66,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Transactional(readOnly = true)
 @Component
@@ -101,6 +107,9 @@ public class PullUtils {
     private AnySearchDAO searchDAO;
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
@@ -130,7 +139,7 @@ public class PullUtils {
             public boolean handle(final ConnectorObject obj) {
                 return found.add(obj);
             }
-        }, MappingUtils.buildOperationOptions(MappingUtils.getPullMappingItems(provision).iterator()));
+        }, MappingUtils.buildOperationOptions(MappingUtils.getPullItems(provision).iterator()));
 
         if (found.isEmpty()) {
             LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
@@ -171,12 +180,10 @@ public class PullUtils {
     private List<String> findByConnObjectKeyItem(
             final String uid, final Provision provision, final AnyUtils anyUtils) {
 
-        List<String> result = new ArrayList<>();
-
         MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
 
         String transfUid = uid;
-        for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(connObjectKeyItem)) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
             List<Object> output = transformer.beforePull(
                     connObjectKeyItem,
                     null,
@@ -186,6 +193,8 @@ public class PullUtils {
             }
         }
 
+        List<String> result = new ArrayList<>();
+
         IntAttrName intAttrName = intAttrNameParser.parse(
                 connObjectKeyItem.getIntAttrName(),
                 provision.getAnyType().getKind());
@@ -323,6 +332,52 @@ public class PullUtils {
         }
     }
 
+    public List<String> findExisting(
+            final String uid,
+            final ConnectorObject connObj,
+            final OrgUnit orgUnit) {
+
+        OrgUnitItem connObjectKeyItem = orgUnit.getConnObjectKeyItem();
+
+        String transfUid = uid;
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
+            List<Object> output = transformer.beforePull(
+                    connObjectKeyItem,
+                    null,
+                    Collections.<Object>singletonList(transfUid));
+            if (output != null && !output.isEmpty()) {
+                transfUid = output.get(0).toString();
+            }
+        }
+
+        List<String> result = new ArrayList<>();
+
+        Realm realm;
+        switch (connObjectKeyItem.getIntAttrName()) {
+            case "key":
+                realm = realmDAO.find(transfUid);
+                if (realm != null) {
+                    result.add(realm.getKey());
+                }
+                break;
+
+            case "name":
+                CollectionUtils.collect(realmDAO.findByName(transfUid), EntityUtils.keyTransformer(), result);
+                break;
+
+            case "fullpath":
+                realm = realmDAO.findByFullPath(transfUid);
+                if (realm != null) {
+                    result.add(realm.getKey());
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
     public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
         Boolean enabled = null;
         if (task.isSyncStatus()) {


[06/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
[SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys


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

Branch: refs/heads/2_0_X
Commit: e21971bf5abb8c9724c464b4ae402ffa2ceb1981
Parents: d540e51
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jul 18 12:20:31 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jul 18 12:20:37 2017 +0200

----------------------------------------------------------------------
 .../syncope/client/cli/commands/info/Info.java  |   2 +-
 .../resource/ResourceResultManager.java         |   8 +-
 .../client/console/bulk/BulkContent.java        |   6 +-
 .../console/commons/status/StatusBean.java      |  31 +-
 .../console/commons/status/StatusUtils.java     |  38 +-
 .../client/console/panels/ConnObjects.java      |   9 +-
 .../client/console/panels/ListViewPanel.java    |   4 +-
 .../panels/ProvisionAuxClassesPanel.java        |  29 +-
 .../console/rest/AbstractAnyRestClient.java     |   5 -
 .../client/console/rest/AnyTypeRestClient.java  |   7 +
 .../console/status/AnyStatusDirectoryPanel.java |   8 +-
 .../console/status/ChangePasswordModal.java     |   4 +-
 .../status/ResourceStatusDirectoryPanel.java    |   3 +-
 .../console/status/ResourceStatusModal.java     |  28 +-
 .../html/form/ActionLinksTogglePanel.java       |   2 +-
 .../console/widgets/ItemTransformerWidget.java  |  83 +++
 .../console/widgets/JEXLTransformerWidget.java  |  20 +-
 .../widgets/MappingItemTransformerWidget.java   |  83 ---
 .../console/wizards/AbstractMappingPanel.java   |  64 +-
 .../client/console/wizards/any/StatusPanel.java |   8 +-
 .../console/wizards/any/UserWizardBuilder.java  |   2 +-
 .../resources/ItemTransformersTogglePanel.java  | 118 ++++
 .../resources/JEXLTransformersTogglePanel.java  |   8 +-
 .../MappingItemTransformersTogglePanel.java     | 121 ----
 .../resources/ProvisionWizardBuilder.java       | 102 +--
 .../wizards/resources/ResourceMappingPanel.java |  75 ++-
 .../wizards/resources/ResourceProvision.java    | 151 +++++
 .../resources/ResourceProvisionPanel.java       | 247 ++-----
 .../META-INF/resources/css/syncopeConsole.css   |   6 +-
 .../widgets/ItemTransformerWidget.properties    |  18 +
 .../widgets/ItemTransformerWidget_it.properties |  18 +
 .../ItemTransformerWidget_pt_BR.properties      |  18 +
 .../widgets/ItemTransformerWidget_ru.properties |  19 +
 .../MappingItemTransformerWidget.properties     |  18 -
 .../MappingItemTransformerWidget_it.properties  |  18 -
 ...appingItemTransformerWidget_pt_BR.properties |  18 -
 .../MappingItemTransformerWidget_ru.properties  |  19 -
 .../console/wizards/AbstractMappingPanel.html   |   2 +-
 .../resources/ItemTransformersTogglePanel.html  |  32 +
 .../ItemTransformersTogglePanel.properties      |  19 +
 .../ItemTransformersTogglePanel_it.properties   |  19 +
 ...ItemTransformersTogglePanel_pt_BR.properties |  19 +
 .../ItemTransformersTogglePanel_ru.properties   |  20 +
 .../MappingItemTransformersTogglePanel.html     |  32 -
 ...appingItemTransformersTogglePanel.properties |  19 -
 ...ingItemTransformersTogglePanel_it.properties |  19 -
 ...ItemTransformersTogglePanel_pt_BR.properties |  19 -
 ...ingItemTransformersTogglePanel_ru.properties |  20 -
 .../resources/ResourceProvisionPanel.html       |   8 -
 .../resources/ResourceProvisionPanel.properties |   5 -
 .../ResourceProvisionPanel_it.properties        |   5 -
 .../ResourceProvisionPanel_pt_BR.properties     |   5 -
 .../ResourceProvisionPanel_ru.properties        |   5 -
 .../syncope/common/lib/info/PlatformInfo.java   |  12 +-
 .../syncope/common/lib/to/ItemContainerTO.java  |  32 +
 .../apache/syncope/common/lib/to/ItemTO.java    | 163 +++++
 .../syncope/common/lib/to/MappingItemTO.java    | 163 -----
 .../apache/syncope/common/lib/to/MappingTO.java |  28 +-
 .../apache/syncope/common/lib/to/OrgUnitTO.java |  62 +-
 .../syncope/core/logic/ResourceLogic.java       |  66 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |   4 +-
 .../init/ClassPathScanImplementationLookup.java |  12 +-
 .../persistence/api/ImplementationLookup.java   |   2 +-
 .../core/persistence/api/dao/RealmDAO.java      |   2 +
 .../api/entity/LinkingMappingItem.java          |   2 +-
 .../persistence/api/entity/resource/Item.java   |  60 ++
 .../api/entity/resource/Mapping.java            |   8 +-
 .../api/entity/resource/MappingItem.java        |  40 +-
 .../api/entity/resource/OrgUnit.java            |  12 +-
 .../api/entity/resource/OrgUnitItem.java        |  26 +
 .../core/persistence/jpa/dao/JPARealmDAO.java   |  11 +
 .../jpa/entity/JPAEntityFactory.java            |   4 +
 .../jpa/entity/resource/AbstractItem.java       | 176 +++++
 .../jpa/entity/resource/JPAMapping.java         |   4 +-
 .../jpa/entity/resource/JPAMappingItem.java     | 157 +----
 .../jpa/entity/resource/JPAOrgUnit.java         |  47 +-
 .../jpa/entity/resource/JPAOrgUnitItem.java     |  72 +++
 .../entity/ExternalResourceValidator.java       |  74 ++-
 .../test/resources/domains/MasterContent.xml    |  12 +-
 .../core/provisioning/api/MappingManager.java   |  32 +
 .../provisioning/api/data/ItemTransformer.java  |  60 ++
 .../api/data/JEXLItemTransformer.java           |  30 +
 .../api/data/JEXLMappingItemTransformer.java    |  30 -
 .../api/data/MappingItemTransformer.java        |  60 --
 .../provisioning/api/pushpull/PullActions.java  |   8 +-
 .../provisioning/java/MappingManagerImpl.java   | 173 ++++-
 .../java/data/AbstractAnyDataBinder.java        |   4 +-
 .../java/data/DefaultItemTransformer.java       |  47 ++
 .../data/DefaultMappingItemTransformer.java     |  54 --
 .../java/data/JEXLItemTransformerImpl.java      | 102 +++
 .../data/JEXLMappingItemTransformerImpl.java    |  99 ---
 .../java/data/ResourceDataBinderImpl.java       |  95 ++-
 .../AbstractPropagationTaskExecutor.java        |  47 +-
 .../propagation/PropagationManagerImpl.java     |  36 +-
 .../pushpull/AbstractPullResultHandler.java     |  38 +-
 .../java/pushpull/DBPasswordPullActions.java    |   5 +-
 .../java/pushpull/DefaultPullActions.java       |   5 +-
 .../java/pushpull/LDAPPasswordPullActions.java  |   5 +-
 .../pushpull/PlainAttrsPullCorrelationRule.java |   6 +-
 .../java/pushpull/PullJobDelegate.java          |  15 +-
 .../provisioning/java/pushpull/PullUtils.java   |  65 +-
 .../pushpull/RealmPullResultHandlerImpl.java    | 638 +++++++++++--------
 .../pushpull/RealmPushResultHandlerImpl.java    |  62 +-
 .../java/utils/ConnObjectUtils.java             |  15 +-
 .../provisioning/java/utils/MappingUtils.java   | 211 +++---
 .../java/ResourceDataBinderTest.java            |   4 +-
 .../console/wizards/SAML2IdPMappingPanel.java   |   8 +-
 .../console/wizards/SAML2IdPWizardBuilder.java  |  12 +-
 .../syncope/common/lib/to/SAML2IdPTO.java       |  18 +-
 .../syncope/core/logic/SAML2IdPLogic.java       |   4 +-
 .../apache/syncope/core/logic/SAML2SPLogic.java |   8 +-
 .../syncope/core/logic/saml2/SAML2IdPCache.java |   4 +-
 .../core/logic/saml2/SAML2IdPEntity.java        |  10 +-
 .../validation/entity/SAML2IdPValidator.java    |   6 +-
 .../java/data/SAML2IdPDataBinderImpl.java       |  10 +-
 .../core/reference/ITImplementationLookup.java  |   8 +-
 .../core/reference/PrefixItemTransformer.java   |  66 ++
 .../reference/PrefixMappingItemTransformer.java |  66 --
 .../fit/core/reference/TestPullActions.java     |   4 +-
 .../syncope/fit/console/BulkActionITCase.java   |   6 +-
 .../syncope/fit/console/RealmsITCase.java       |  28 +-
 .../syncope/fit/console/TopologyITCase.java     |  40 +-
 .../syncope/fit/core/ConnectorITCase.java       |   4 +-
 .../apache/syncope/fit/core/GroupITCase.java    |   6 +-
 .../syncope/fit/core/MembershipITCase.java      |  12 +-
 .../syncope/fit/core/MigrationITCase.java       |  34 +-
 .../syncope/fit/core/MultitenancyITCase.java    |  10 +-
 .../syncope/fit/core/PropagationTaskITCase.java |  10 +-
 .../apache/syncope/fit/core/PullTaskITCase.java |  19 +-
 .../apache/syncope/fit/core/PushTaskITCase.java |   4 +-
 .../apache/syncope/fit/core/RealmITCase.java    |  52 +-
 .../apache/syncope/fit/core/ResourceITCase.java |  60 +-
 .../apache/syncope/fit/core/SAML2ITCase.java    |   4 +-
 .../syncope/fit/core/UserIssuesITCase.java      |  12 +-
 .../apache/syncope/fit/core/VirAttrITCase.java  |  16 +-
 135 files changed, 3047 insertions(+), 2357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
index 369ee8e..7df6fb7 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/info/Info.java
@@ -131,7 +131,7 @@ public class Info {
 
     public void mappingItemTransformers() {
         try {
-            infoResultManager.printMappingItemTransformers(platformInfo.getMappingItemTransformers());
+            infoResultManager.printMappingItemTransformers(platformInfo.getItemTransformers());
         } catch (final Exception ex) {
             LOG.error("Information error", ex);
             infoResultManager.genericError(ex.getMessage());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
index aefb7c1..7e57e01 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/resource/ResourceResultManager.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.cli.commands.resource;
 import java.util.List;
 import java.util.Map;
 import org.apache.syncope.client.cli.commands.CommonsResultManager;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -74,8 +74,8 @@ public class ResourceResultManager extends CommonsResultManager {
         printMappingItem(mappingTO.getItems());
     }
 
-    private void printMappingItem(final List<MappingItemTO> mappingItemTOs) {
-        for (final MappingItemTO mappingItemTO : mappingItemTOs) {
+    private void printMappingItem(final List<ItemTO> mappingItemTOs) {
+        for (final ItemTO mappingItemTO : mappingItemTOs) {
             System.out.println("             mapping key: " + mappingItemTO.getKey());
             System.out.println("             internal attribute name: " + mappingItemTO.getIntAttrName());
             System.out.println("             external attribute name: " + mappingItemTO.getExtAttrName());
@@ -85,7 +85,7 @@ public class ResourceResultManager extends CommonsResultManager {
             System.out.println("             JEXL pull transformer: "
                     + mappingItemTO.getPullJEXLTransformer());
             System.out.println("             transformers classes: "
-                    + mappingItemTO.getMappingItemTransformerClassNames());
+                    + mappingItemTO.getTransformerClassNames());
             System.out.println("             purpose: " + mappingItemTO.getPurpose());
             System.out.println("             connector object key: " + mappingItemTO.isConnObjectKey());
             System.out.println("             password: " + mappingItemTO.isPassword());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
index 2a46141..de3ceb7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/bulk/BulkContent.java
@@ -171,11 +171,11 @@ public class BulkContent<T extends Serializable, S> extends MultilevelPanel.Seco
                             for (T bean : items) {
                                 final StatusBean sb = StatusBean.class.cast(bean);
                                 final List<StatusBean> sblist;
-                                if (beans.containsKey(sb.getAnyKey())) {
-                                    sblist = beans.get(sb.getAnyKey());
+                                if (beans.containsKey(sb.getKey())) {
+                                    sblist = beans.get(sb.getKey());
                                 } else {
                                     sblist = new ArrayList<>();
-                                    beans.put(sb.getAnyKey(), sblist);
+                                    beans.put(sb.getKey(), sblist);
                                 }
                                 sblist.add(sb);
                             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
index a34425a..c8bba79 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
@@ -25,17 +25,18 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 
 public class StatusBean implements Serializable {
 
     private static final long serialVersionUID = -5207260204921071129L;
 
-    private final String anyKey;
+    private final String key;
 
-    private final String anyName;
+    private final String name;
 
-    private final String resourceName;
+    private final String resource;
 
     private String connObjectLink;
 
@@ -44,11 +45,17 @@ public class StatusBean implements Serializable {
     private boolean linked = true;
 
     public StatusBean(final AnyTO any, final String resourceName) {
-        this.anyKey = any.getKey();
-        this.anyName = any instanceof UserTO
+        this.key = any.getKey();
+        this.name = any instanceof UserTO
                 ? ((UserTO) any).getUsername()
                 : any instanceof GroupTO ? ((GroupTO) any).getName() : String.valueOf(any.getKey());
-        this.resourceName = resourceName;
+        this.resource = resourceName;
+    }
+
+    public StatusBean(final RealmTO realm, final String resourceName) {
+        this.key = realm.getKey();
+        this.name = realm.getFullPath();
+        this.resource = resourceName;
     }
 
     public String getConnObjectLink() {
@@ -59,8 +66,8 @@ public class StatusBean implements Serializable {
         this.connObjectLink = connObjectLink;
     }
 
-    public String getResourceName() {
-        return resourceName;
+    public String getResource() {
+        return resource;
     }
 
     public Status getStatus() {
@@ -71,12 +78,12 @@ public class StatusBean implements Serializable {
         this.status = status;
     }
 
-    public String getAnyKey() {
-        return anyKey;
+    public String getKey() {
+        return key;
     }
 
-    public String getAnyName() {
-        return anyName;
+    public String getName() {
+        return name;
     }
 
     public boolean isLinked() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index 6da9246..8a9aa09 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.patch.StatusPatch;
 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.RealmTO;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.basic.Label;
@@ -88,7 +89,7 @@ public class StatusUtils implements Serializable {
             final AnyTO anyTO,
             final String resourceName,
             final ConnObjectTO objectTO,
-            final boolean isGroup) {
+            final boolean notUser) {
 
         final StatusBean statusBean = new StatusBean(anyTO, resourceName);
 
@@ -96,7 +97,32 @@ public class StatusUtils implements Serializable {
             final Boolean enabled = isEnabled(objectTO);
 
             final Status status = enabled == null
-                    ? (isGroup ? Status.ACTIVE : Status.UNDEFINED)
+                    ? (notUser ? Status.ACTIVE : Status.UNDEFINED)
+                    : enabled
+                            ? Status.ACTIVE
+                            : Status.SUSPENDED;
+
+            String connObjectLink = getConnObjectLink(objectTO);
+
+            statusBean.setStatus(status);
+            statusBean.setConnObjectLink(connObjectLink);
+        }
+
+        return statusBean;
+    }
+
+    public StatusBean getStatusBean(
+            final RealmTO anyTO,
+            final String resourceName,
+            final ConnObjectTO objectTO) {
+
+        final StatusBean statusBean = new StatusBean(anyTO, resourceName);
+
+        if (objectTO != null) {
+            final Boolean enabled = isEnabled(objectTO);
+
+            final Status status = enabled == null
+                    ? Status.ACTIVE
                     : enabled
                             ? Status.ACTIVE
                             : Status.SUSPENDED;
@@ -129,10 +155,10 @@ public class StatusUtils implements Serializable {
         builder.value(password);
 
         for (StatusBean status : statuses) {
-            if (Constants.SYNCOPE.equalsIgnoreCase(status.getResourceName())) {
+            if (Constants.SYNCOPE.equalsIgnoreCase(status.getResource())) {
                 builder.onSyncope(true);
             } else {
-                builder.resource(status.getResourceName());
+                builder.resource(status.getResource());
             }
         }
         return builder.build();
@@ -150,10 +176,10 @@ public class StatusUtils implements Serializable {
             if (enable == null
                     || (enable && !status.getStatus().isActive()) || (!enable && status.getStatus().isActive())) {
 
-                if ("syncope".equalsIgnoreCase(status.getResourceName())) {
+                if ("syncope".equalsIgnoreCase(status.getResource())) {
                     statusPatch.setOnSyncope(true);
                 } else {
-                    statusPatch.getResources().add(status.getResourceName());
+                    statusPatch.getResources().add(status.getResource());
                 }
 
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
index 595ff5a..d29ce1a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
@@ -19,10 +19,12 @@
 package org.apache.syncope.client.console.panels;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -48,16 +50,17 @@ public class ConnObjects extends Panel implements ModalPanel {
     public ConnObjects(final ResourceTO resource, final PageReference pageRef) {
         super(BaseModal.CONTENT_ID);
 
-        List<String> availableAnyTypes = CollectionUtils.collect(resource.getProvisions(),
-                new Transformer<ProvisionTO, String>() {
+        List<String> availableAnyTypes = CollectionUtils.collect(
+                resource.getProvisions(), new Transformer<ProvisionTO, String>() {
 
             @Override
             public String transform(final ProvisionTO provision) {
                 return provision.getAnyType();
             }
         }, new ArrayList<String>());
+        Collections.sort(availableAnyTypes, new AnyTypeRestClient.AnyTypeKeyComparator());
         if (resource.getOrgUnit() != null) {
-            availableAnyTypes.add(SyncopeConstants.REALM_ANYTYPE);
+            availableAnyTypes.add(0, SyncopeConstants.REALM_ANYTYPE);
         }
 
         anyTypes = new AjaxDropDownChoicePanel<>("anyTypes", "anyTypes", new Model<String>());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 16c4b77..e028cc3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -241,7 +241,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             super(pageRef);
             this.reference = reference;
             this.items = null;
-            this.actions = new ActionsPanel<T>("actions", null);
+            this.actions = new ActionsPanel<>("actions", null);
         }
 
         public Builder<T> setModel(final IModel<? extends Collection<T>> model) {
@@ -376,7 +376,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
             return new ListViewPanel<T>(
                     id, items, reference, includes, actions, check, reuseItem, wizardInModal, model) {
 
-                private static final long serialVersionUID = 1L;
+                private static final long serialVersionUID = -1715389337530657988L;
 
                 @Override
                 protected Component getValueComponent(final String key, final T bean) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
index 3e7116c..574939a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.panels;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
@@ -27,6 +28,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.util.ListModel;
 
@@ -47,16 +49,27 @@ public class ProvisionAuxClassesPanel extends Panel {
     protected void onBeforeRender() {
         super.onBeforeRender();
 
-        AnyTypeTO anyType = new AnyTypeRestClient().read(provisionTO.getAnyType());
-        List<String> choices = new ArrayList<>();
-        for (AnyTypeClassTO aux : new AnyTypeClassRestClient().list()) {
-            if (!anyType.getClasses().contains(aux.getKey())) {
-                choices.add(aux.getKey());
+        IModel<List<String>> model;
+        List<String> choices;
+        if (provisionTO == null) {
+            model = new ListModel<>(Collections.<String>emptyList());
+            choices = Collections.emptyList();
+        } else {
+            model = new PropertyModel<>(provisionTO, "auxClasses");
+
+            AnyTypeTO anyType = new AnyTypeRestClient().read(provisionTO.getAnyType());
+            choices = new ArrayList<>();
+            for (AnyTypeClassTO aux : new AnyTypeClassRestClient().list()) {
+                if (!anyType.getClasses().contains(aux.getKey())) {
+                    choices.add(aux.getKey());
+                }
             }
         }
-        addOrReplace(new AjaxPalettePanel.Builder<String>().build("auxClasses",
-                new PropertyModel<List<String>>(provisionTO, "auxClasses"),
-                new ListModel<>(choices)).hideLabel().setOutputMarkupId(true));
+        addOrReplace(
+                new AjaxPalettePanel.Builder<String>().build("auxClasses", model, new ListModel<>(choices)).
+                        hideLabel().
+                        setOutputMarkupId(true).
+                        setEnabled(provisionTO != null));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
index 9d7d1d7..1386e62 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
@@ -28,7 +28,6 @@ import org.apache.syncope.common.lib.patch.AssociationPatch;
 import org.apache.syncope.common.lib.patch.DeassociationPatch;
 import org.apache.syncope.common.lib.patch.StatusPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.ResourceAssociationAction;
@@ -188,8 +187,4 @@ public abstract class AbstractAnyRestClient<TO extends AnyTO, P extends AnyPatch
         }
         return result;
     }
-
-    public BulkActionResult bulkAction(final BulkAction action) {
-        return getService(getAnyServiceClass()).bulk(action).readEntity(BulkActionResult.class);
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
index 86d27c1..fc1e004 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AnyTypeRestClient.java
@@ -24,6 +24,7 @@ import java.util.Comparator;
 import java.util.List;
 import org.apache.commons.collections4.ComparatorUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
@@ -103,6 +104,12 @@ public class AnyTypeRestClient extends BaseRestClient {
 
         @Override
         public int compare(final String o1, final String o2) {
+            if (SyncopeConstants.REALM_ANYTYPE.equals(o1)) {
+                return -1;
+            }
+            if (SyncopeConstants.REALM_ANYTYPE.equals(o2)) {
+                return 1;
+            }
             if (AnyTypeKind.USER.name().equals(o1)) {
                 return -1;
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
index 992f3fb..6fcc84b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/AnyStatusDirectoryPanel.java
@@ -121,7 +121,7 @@ public class AnyStatusDirectoryPanel
                     final String componentId,
                     final IModel<StatusBean> model) {
 
-                cellItem.add(new Label(componentId, model.getObject().getResourceName()) {
+                cellItem.add(new Label(componentId, model.getObject().getResource()) {
 
                     private static final long serialVersionUID = 8432079838783825801L;
 
@@ -171,14 +171,14 @@ public class AnyStatusDirectoryPanel
             @Override
             protected boolean statusCondition(final StatusBean bean) {
                 return bean != null && bean.getConnObjectLink() != null
-                        && !bean.getResourceName().equalsIgnoreCase(Constants.SYNCOPE);
+                        && !bean.getResource().equalsIgnoreCase(Constants.SYNCOPE);
             }
 
             @Override
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
-                multiLevelPanelRef.next(bean.getResourceName(),
+                multiLevelPanelRef.next(bean.getResource(),
                         new ConnObjectDetails(resourceRestClient.readConnObject(
-                                bean.getResourceName(), anyTO.getType(), anyTO.getKey())), target);
+                                bean.getResource(), anyTO.getType(), anyTO.getKey())), target);
                 target.add(multiLevelPanelRef);
                 AnyStatusDirectoryPanel.this.getTogglePanel().close(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
index dff996f..336f4d1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
@@ -80,10 +80,10 @@ public class ChangePasswordModal extends AbstractModalPanel<AnyWrapper<UserTO>>
                 final List<String> resources = new ArrayList<String>();
                 boolean isOnSyncope = false;
                 for (StatusBean sb : statusModel.getObject()) {
-                    if (sb.getResourceName().equals(Constants.SYNCOPE)) {
+                    if (sb.getResource().equals(Constants.SYNCOPE)) {
                         isOnSyncope = true;
                     } else {
-                        resources.add(sb.getResourceName());
+                        resources.add(sb.getResource());
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
index 93a0ffa..2844a74 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusDirectoryPanel.java
@@ -36,6 +36,7 @@ import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.UserRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -145,7 +146,7 @@ public class ResourceStatusDirectoryPanel
 
     @Override
     protected ResourceStatusDataProvider dataProvider() {
-        return new ResourceStatusDataProvider(type, resourceTO.getKey(), rows, "/");
+        return new ResourceStatusDataProvider(type, resourceTO.getKey(), rows, SyncopeConstants.ROOT_REALM);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
index 1a379a9..960bd12 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
@@ -18,7 +18,11 @@
  */
 package org.apache.syncope.client.console.status;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.status.StatusBean;
@@ -28,11 +32,12 @@ import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
 
 public class ResourceStatusModal extends StatusModal<ResourceTO> {
@@ -44,23 +49,26 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
     public ResourceStatusModal(
             final BaseModal<?> baseModal,
             final PageReference pageReference,
-            final ResourceTO resourceTO) {
+            final ResourceTO resource) {
 
-        super(baseModal, pageReference, resourceTO, null, false);
+        super(baseModal, pageReference, resource, null, false);
 
-        final LoadableDetachableModel<List<String>> types = new LoadableDetachableModel<List<String>>() {
-
-            private static final long serialVersionUID = 5275935387613157437L;
+        List<String> availableAnyTypes = CollectionUtils.collect(
+                resource.getProvisions(), new Transformer<ProvisionTO, String>() {
 
             @Override
-            protected List<String> load() {
-                return new AnyTypeRestClient().list();
+            public String transform(final ProvisionTO provision) {
+                return provision.getAnyType();
             }
-        };
+        }, new ArrayList<String>());
+        Collections.sort(availableAnyTypes, new AnyTypeRestClient.AnyTypeKeyComparator());
+        if (resource.getOrgUnit() != null) {
+            availableAnyTypes.add(0, SyncopeConstants.REALM_ANYTYPE);
+        }
 
         AjaxDropDownChoicePanel<String> anyTypes =
                 new AjaxDropDownChoicePanel<>("anyTypes", "anyTypes", typeModel, false);
-        anyTypes.setChoices(types);
+        anyTypes.setChoices(availableAnyTypes);
         anyTypes.hideLabel();
         add(anyTypes);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
index 78c175a..fb8ab83 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
@@ -99,7 +99,7 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
         } else if (modelObject instanceof EntityTO) {
             header = ((EntityTO) modelObject).getKey();
         } else if (modelObject instanceof StatusBean) {
-            header = ((StatusBean) modelObject).getResourceName();
+            header = ((StatusBean) modelObject).getResource();
         } else if (modelObject instanceof PolicyRuleWrapper) {
             header = ((PolicyRuleWrapper) modelObject).getName();
         } else if (modelObject instanceof PolicyRuleWrapper) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
new file mode 100644
index 0000000..9aa4142
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
+import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconTypeBuilder;
+import java.util.List;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class ItemTransformerWidget extends AlertWidget<String> {
+
+    private static final long serialVersionUID = 7667120094526529934L;
+
+    private final ItemTO item;
+
+    private final ItemTransformersTogglePanel transformers;
+
+    public ItemTransformerWidget(
+            final String id,
+            final ItemTO item,
+            final ItemTransformersTogglePanel transformers) {
+
+        super(id);
+        this.item = item;
+        this.transformers = transformers;
+        setOutputMarkupId(true);
+    }
+
+    @Override
+    protected IModel<List<String>> getLatestAlerts() {
+        return new ListModel<String>() {
+
+            private static final long serialVersionUID = 1232998477036705088L;
+
+            @Override
+            public List<String> getObject() {
+                return item.getTransformerClassNames();
+            }
+        };
+    }
+
+    @Override
+    protected AbstractLink getEventsLink(final String linkid) {
+        return new AjaxLink<String>(linkid) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                transformers.setItem(target, ItemTransformerWidget.this.item);
+                transformers.toggle(target, true);
+            }
+        };
+    }
+
+    @Override
+    protected Icon getIcon(final String iconid) {
+        return new Icon(
+                iconid, FontAwesomeIconTypeBuilder.on(FontAwesomeIconTypeBuilder.FontAwesomeGraphic.magic).build());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
index a4dec3d..6c4dd7b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.link.AbstractLink;
@@ -35,21 +35,21 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
 
     private static final long serialVersionUID = 7667120094526529934L;
 
-    private final MappingItemTO mapItem;
+    private final ItemTO item;
 
     private final JEXLTransformersTogglePanel transformers;
 
     public JEXLTransformerWidget(
             final String id,
-            final MappingItemTO mapItem,
+            final ItemTO item,
             final JEXLTransformersTogglePanel transformers) {
 
         super(id);
         setOutputMarkupId(true);
 
-        this.mapItem = mapItem;
+        this.item = item;
         this.transformers = transformers;
-        
+
         this.latestAlertsList.setVisible(false);
     }
 
@@ -62,11 +62,11 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
             @Override
             public List<String> getObject() {
                 List<String> result = new ArrayList<>();
-                if (StringUtils.isNotBlank(mapItem.getPropagationJEXLTransformer())) {
-                    result.add(mapItem.getPropagationJEXLTransformer());
+                if (StringUtils.isNotBlank(item.getPropagationJEXLTransformer())) {
+                    result.add(item.getPropagationJEXLTransformer());
                 }
-                if (StringUtils.isNotBlank(mapItem.getPullJEXLTransformer())) {
-                    result.add(mapItem.getPullJEXLTransformer());
+                if (StringUtils.isNotBlank(item.getPullJEXLTransformer())) {
+                    result.add(item.getPullJEXLTransformer());
                 }
                 return result;
             }
@@ -81,7 +81,7 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                transformers.setMappingItem(target, JEXLTransformerWidget.this.mapItem);
+                transformers.setItem(target, JEXLTransformerWidget.this.item);
                 transformers.toggle(target, true);
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
deleted file mode 100644
index 6e363dd..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.widgets;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
-import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconTypeBuilder;
-import java.util.List;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.markup.html.link.AbstractLink;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.util.ListModel;
-
-public class MappingItemTransformerWidget extends AlertWidget<String> {
-
-    private static final long serialVersionUID = 7667120094526529934L;
-
-    private final MappingItemTO mapItem;
-
-    private final MappingItemTransformersTogglePanel transformers;
-
-    public MappingItemTransformerWidget(
-            final String id,
-            final MappingItemTO mapItem,
-            final MappingItemTransformersTogglePanel transformers) {
-
-        super(id);
-        this.mapItem = mapItem;
-        this.transformers = transformers;
-        setOutputMarkupId(true);
-    }
-
-    @Override
-    protected IModel<List<String>> getLatestAlerts() {
-        return new ListModel<String>() {
-
-            private static final long serialVersionUID = 1232998477036705088L;
-
-            @Override
-            public List<String> getObject() {
-                return mapItem.getMappingItemTransformerClassNames();
-            }
-        };
-    }
-
-    @Override
-    protected AbstractLink getEventsLink(final String linkid) {
-        return new AjaxLink<String>(linkid) {
-
-            private static final long serialVersionUID = -7978723352517770644L;
-
-            @Override
-            public void onClick(final AjaxRequestTarget target) {
-                transformers.setMappingItem(target, MappingItemTransformerWidget.this.mapItem);
-                transformers.toggle(target, true);
-            }
-        };
-    }
-
-    @Override
-    protected Icon getIcon(final String iconid) {
-        return new Icon(
-                iconid, FontAwesomeIconTypeBuilder.on(FontAwesomeIconTypeBuilder.FontAwesomeGraphic.magic).build());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
index 6872cde..5532f86 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AbstractMappingPanel.java
@@ -44,12 +44,12 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPan
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel;
 import org.apache.syncope.client.console.widgets.JEXLTransformerWidget;
-import org.apache.syncope.client.console.widgets.MappingItemTransformerWidget;
+import org.apache.syncope.client.console.widgets.ItemTransformerWidget;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
@@ -120,20 +120,18 @@ public abstract class AbstractMappingPanel extends Panel {
     /**
      * All mappings.
      */
-    protected final ListView<MappingItemTO> mappings;
+    protected final ListView<ItemTO> mappings;
 
     /**
      * Mapping container.
      */
     protected final WebMarkupContainer mappingContainer;
 
-    protected final IModel<List<MappingItemTO>> model;
-
     public AbstractMappingPanel(
             final String id,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ItemTransformersTogglePanel itemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers,
-            final IModel<List<MappingItemTO>> model,
+            final IModel<List<ItemTO>> model,
             final boolean addMappingBtnVisible,
             final boolean hidePurpose,
             final MappingPurpose defaultPurpose) {
@@ -141,8 +139,6 @@ public abstract class AbstractMappingPanel extends Panel {
         super(id);
         setOutputMarkupId(true);
 
-        this.model = model;
-
         mappingContainer = new WebMarkupContainer("mappingContainer");
         mappingContainer.setOutputMarkupId(true);
         add(mappingContainer);
@@ -173,10 +169,10 @@ public abstract class AbstractMappingPanel extends Panel {
 
         mappingContainer.add(Constants.getJEXLPopover(this, TooltipConfig.Placement.bottom));
 
-        Collections.sort(model.getObject(), new Comparator<MappingItemTO>() {
+        Collections.sort(model.getObject(), new Comparator<ItemTO>() {
 
             @Override
-            public int compare(final MappingItemTO left, final MappingItemTO right) {
+            public int compare(final ItemTO left, final ItemTO right) {
                 int compared;
                 if (left == null && right == null) {
                     compared = 0;
@@ -216,15 +212,15 @@ public abstract class AbstractMappingPanel extends Panel {
             }
         });
 
-        mappings = new ListView<MappingItemTO>("mappings", model.getObject()) {
+        mappings = new ListView<ItemTO>("mappings", model) {
 
             private static final long serialVersionUID = 4949588177564901031L;
 
             @Override
-            protected void populateItem(final ListItem<MappingItemTO> item) {
-                final MappingItemTO mapItem = item.getModelObject();
-                if (mapItem.getPurpose() == null) {
-                    mapItem.setPurpose(defaultPurpose);
+            protected void populateItem(final ListItem<ItemTO> item) {
+                final ItemTO itemTO = item.getModelObject();
+                if (itemTO.getPurpose() == null) {
+                    itemTO.setPurpose(defaultPurpose);
                 }
 
                 //--------------------------------
@@ -233,7 +229,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 AjaxTextFieldPanel intAttrName = new AjaxTextFieldPanel(
                         "intAttrName",
                         getString("intAttrName"),
-                        new PropertyModel<String>(mapItem, "intAttrName"),
+                        new PropertyModel<String>(itemTO, "intAttrName"),
                         false);
                 intAttrName.setChoices(Collections.<String>emptyList());
                 intAttrName.setRequired(true).hideLabel();
@@ -246,10 +242,10 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxTextFieldPanel extAttrName = new AjaxTextFieldPanel(
                         "extAttrName",
                         getString("extAttrName"),
-                        new PropertyModel<String>(mapItem, "extAttrName"));
+                        new PropertyModel<String>(itemTO, "extAttrName"));
                 extAttrName.setChoices(getExtAttrNames().getObject());
 
-                boolean required = !mapItem.isPassword();
+                boolean required = !itemTO.isPassword();
                 extAttrName.setRequired(required).hideLabel();
                 extAttrName.setEnabled(required);
                 item.add(extAttrName);
@@ -259,14 +255,14 @@ public abstract class AbstractMappingPanel extends Panel {
                 // JEXL transformers
                 // -------------------------------
                 item.add(new JEXLTransformerWidget(
-                        "jexlTransformers", mapItem, jexlTransformers).setRenderBodyOnly(true));
+                        "jexlTransformers", itemTO, jexlTransformers).setRenderBodyOnly(true));
                 // -------------------------------
 
                 //--------------------------------
                 // Mapping item transformers
                 // -------------------------------
-                item.add(new MappingItemTransformerWidget(
-                        "mappingItemTransformers", mapItem, mapItemTransformers).setRenderBodyOnly(true));
+                item.add(new ItemTransformerWidget(
+                        "itemTransformers", itemTO, itemTransformers).setRenderBodyOnly(true));
                 // -------------------------------
 
                 //--------------------------------
@@ -275,10 +271,10 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxTextFieldPanel mandatory = new AjaxTextFieldPanel(
                         "mandatoryCondition",
                         new ResourceModel("mandatoryCondition", "mandatoryCondition").getObject(),
-                        new PropertyModel<String>(mapItem, "mandatoryCondition"));
+                        new PropertyModel<String>(itemTO, "mandatoryCondition"));
                 mandatory.hideLabel();
                 mandatory.setChoices(Arrays.asList(new String[] { "true", "false" }));
-                mandatory.setEnabled(!mapItem.isConnObjectKey());
+                mandatory.setEnabled(!itemTO.isConnObjectKey());
                 item.add(mandatory);
                 // -------------------------------
 
@@ -288,7 +284,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxCheckBoxPanel connObjectKey = new AjaxCheckBoxPanel(
                         "connObjectKey",
                         new ResourceModel("connObjectKey", "connObjectKey").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "connObjectKey"), false);
+                        new PropertyModel<Boolean>(itemTO, "connObjectKey"), false);
                 connObjectKey.hideLabel();
                 item.add(connObjectKey);
                 // -------------------------------
@@ -299,7 +295,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel(
                         "password",
                         new ResourceModel("password", "password").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "password"), false);
+                        new PropertyModel<Boolean>(itemTO, "password"), false);
                 item.add(password.hideLabel());
                 // -------------------------------
 
@@ -310,7 +306,7 @@ public abstract class AbstractMappingPanel extends Panel {
                 purpose.setOutputMarkupId(true);
 
                 final MappingPurposePanel purposeActions = new MappingPurposePanel(
-                        "purposeActions", new PropertyModel<MappingPurpose>(mapItem, "purpose"), purpose);
+                        "purposeActions", new PropertyModel<MappingPurpose>(itemTO, "purpose"), purpose);
                 purpose.add(purposeActions.setRenderBodyOnly(true));
                 item.add(purpose);
                 // -------------------------------
@@ -327,7 +323,7 @@ public abstract class AbstractMappingPanel extends Panel {
                     public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
                         int index = -1;
                         for (int i = 0; i < model.getObject().size() && index == -1; i++) {
-                            if (mapItem.equals(model.getObject().get(i))) {
+                            if (itemTO.equals(model.getObject().get(i))) {
                                 index = i;
                             }
                         }
@@ -358,11 +354,11 @@ public abstract class AbstractMappingPanel extends Panel {
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
                         if (connObjectKey.getModelObject()) {
-                            mapItem.setMandatoryCondition("true");
+                            itemTO.setMandatoryCondition("true");
                             mandatory.setModelObject("true");
                             mandatory.setEnabled(false);
                         } else {
-                            mapItem.setMandatoryCondition("false");
+                            itemTO.setMandatoryCondition("false");
                             mandatory.setModelObject("false");
                             mandatory.setEnabled(true);
                         }
@@ -395,11 +391,11 @@ public abstract class AbstractMappingPanel extends Panel {
 
                     // Changes required by clone ....
                     extAttrName.setEnabled(true);
-                    if (mapItem.isPassword()) {
+                    if (itemTO.isPassword()) {
                         // re-enable if and only if cloned object mapping item was a password
                         intAttrName.setEnabled(true);
                     }
-                    mapItem.setPassword(false);
+                    itemTO.setPassword(false);
                 }
 
                 if (hidePurpose) {
@@ -417,7 +413,7 @@ public abstract class AbstractMappingPanel extends Panel {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                model.getObject().add(new MappingItemTO());
+                model.getObject().add(new ItemTO());
                 target.add(AbstractMappingPanel.this);
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 4ce8868..565c985 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -121,7 +121,7 @@ public class StatusPanel extends Panel {
         }
 
         statusBeans.add(syncope);
-        initialStatusBeanMap.put(syncope.getResourceName(), syncope);
+        initialStatusBeanMap.put(syncope.getResource(), syncope);
 
         for (Pair<ConnObjectTO, ConnObjectWrapper> pair : connObjects) {
             ConnObjectWrapper entry = pair.getRight();
@@ -164,14 +164,14 @@ public class StatusPanel extends Panel {
             @Override
             protected boolean statusCondition(final StatusBean bean) {
                 final Pair<ConnObjectTO, ConnObjectTO> pair
-                        = getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+                        = getConnObjectTO(bean.getKey(), bean.getResource(), connObjects);
 
                 return pair != null && pair.getRight() != null;
             }
 
             @Override
             public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
-                mlp.next(bean.getResourceName(), new RemoteAnyPanel(bean, connObjects), target);
+                mlp.next(bean.getResource(), new RemoteAnyPanel(bean, connObjects), target);
             }
         };
 
@@ -225,7 +225,7 @@ public class StatusPanel extends Panel {
 
         @Override
         protected final Pair<ConnObjectTO, ConnObjectTO> getConnObjectTO() {
-            return StatusPanel.this.getConnObjectTO(bean.getAnyKey(), bean.getResourceName(), connObjects);
+            return StatusPanel.this.getConnObjectTO(bean.getKey(), bean.getResource(), connObjects);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 6cf6023..44be252 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -39,7 +39,7 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
     private final UserRestClient userRestClient = new UserRestClient();
 
     /**
-     * Costructor to be used for templating only.
+     * Constructor to be used for templating only.
      *
      * @param anyTypeClasses any type classes.
      * @param formLayoutInfo form layout.

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
new file mode 100644
index 0000000..6e37955
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wizards.resources;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.panels.TogglePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.util.ListModel;
+
+public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
+
+    private static final long serialVersionUID = -3195479265440591519L;
+
+    private ItemTO item;
+
+    public ItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
+        super("outer", "itemTransformersTogglePanel", pageRef);
+
+        final LoadableDetachableModel<List<String>> model = new LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                // [!] this is required to disable changed with close button
+                return item == null
+                        ? Collections.<String>emptyList()
+                        : new ArrayList<>(item.getTransformerClassNames());
+            }
+        };
+
+        Form<?> form = new Form<>("form");
+        addInnerObject(form);
+
+        form.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).setRenderer(new IChoiceRenderer<String>() {
+
+            private static final long serialVersionUID = 3464376099975468136L;
+
+            private static final int MAX_LENGTH = 50;
+
+            @Override
+            public Object getDisplayValue(final String object) {
+                if (object.length() > MAX_LENGTH) {
+                    return "..." + object.substring(object.length() - MAX_LENGTH);
+                } else {
+                    return object;
+                }
+            }
+
+            @Override
+            public String getIdValue(final String object, final int index) {
+                return object;
+            }
+
+            @Override
+            public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
+                return id;
+            }
+        }).build(
+                "classes",
+                model,
+                new ListModel<>(new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getItemTransformers()))).
+                hideLabel().setEnabled(true).setOutputMarkupId(true));
+
+        form.add(new AjaxSubmitLink("submit", form) {
+
+            private static final long serialVersionUID = 5538299138211283825L;
+
+            @Override
+            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                toggle(target, false);
+
+                // [!] this is required to disable changed with close button
+                item.getTransformerClassNames().clear();
+                item.getTransformerClassNames().addAll(model.getObject());
+
+                target.add(container);
+            }
+
+        });
+    }
+
+    public ItemTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+        this.item = item;
+        setHeader(target, StringUtils.EMPTY);
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
index 759b708..da3847b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/JEXLTransformersTogglePanel.java
@@ -22,7 +22,7 @@ import java.io.Serializable;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.panels.TogglePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
@@ -69,9 +69,9 @@ public class JEXLTransformersTogglePanel extends TogglePanel<Serializable> {
         });
     }
 
-    public JEXLTransformersTogglePanel setMappingItem(final AjaxRequestTarget target, final MappingItemTO mapItem) {
-        this.propagationJEXLTransformer.setNewModel(new PropertyModel<String>(mapItem, "propagationJEXLTransformer"));
-        this.pullJEXLTransformer.setNewModel(new PropertyModel<String>(mapItem, "pullJEXLTransformer"));
+    public JEXLTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+        this.propagationJEXLTransformer.setNewModel(new PropertyModel<String>(item, "propagationJEXLTransformer"));
+        this.pullJEXLTransformer.setNewModel(new PropertyModel<String>(item, "pullJEXLTransformer"));
         setHeader(target, StringUtils.EMPTY);
         return this;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
deleted file mode 100644
index 3298d20..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.wizards.resources;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.panels.TogglePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.IChoiceRenderer;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.util.ListModel;
-
-public class MappingItemTransformersTogglePanel extends TogglePanel<Serializable> {
-
-    private static final long serialVersionUID = -3195479265440591519L;
-
-    private MappingItemTO mapItem;
-
-    public MappingItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
-        super("outer", "mappingItemTransformersTogglePanel", pageRef);
-
-        final LoadableDetachableModel<List<String>> model = new LoadableDetachableModel<List<String>>() {
-
-            private static final long serialVersionUID = 5275935387613157437L;
-
-            @Override
-            protected List<String> load() {
-                // [!] this is required to disable changed with close button
-                return mapItem == null
-                        ? Collections.<String>emptyList()
-                        : new ArrayList<>(mapItem.getMappingItemTransformerClassNames());
-            }
-        };
-
-        Form<?> form = new Form<>("form");
-        addInnerObject(form);
-
-        form.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).setRenderer(new IChoiceRenderer<String>() {
-
-            private static final long serialVersionUID = 3464376099975468136L;
-
-            private static final int MAX_LENGTH = 50;
-
-            @Override
-            public Object getDisplayValue(final String object) {
-                if (object.length() > MAX_LENGTH) {
-                    return "..." + object.substring(object.length() - MAX_LENGTH);
-                } else {
-                    return object;
-                }
-            }
-
-            @Override
-            public String getIdValue(final String object, final int index) {
-                return object;
-            }
-
-            @Override
-            public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
-                return id;
-            }
-        }).build(
-                "classes",
-                model,
-                new ListModel<>(
-                        new ArrayList<>(SyncopeConsoleSession.get().getPlatformInfo().getMappingItemTransformers()))).
-                hideLabel().setEnabled(true).setOutputMarkupId(true));
-
-        form.add(new AjaxSubmitLink("submit", form) {
-
-            private static final long serialVersionUID = 5538299138211283825L;
-
-            @Override
-            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-                toggle(target, false);
-
-                // [!] this is required to disable changed with close button
-                mapItem.getMappingItemTransformerClassNames().clear();
-                mapItem.getMappingItemTransformerClassNames().addAll(model.getObject());
-
-                target.add(container);
-            }
-
-        });
-    }
-
-    public MappingItemTransformersTogglePanel setMappingItem(
-            final AjaxRequestTarget target, final MappingItemTO mapItem) {
-
-        this.mapItem = mapItem;
-        setHeader(target, StringUtils.EMPTY);
-        return this;
-    }
-}


[08/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
index fc711ca..c4be4e2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPullResultHandlerImpl.java
@@ -18,14 +18,10 @@
  */
 package org.apache.syncope.core.provisioning.java.pushpull;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -47,14 +43,13 @@ import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
 import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
-import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
-import org.identityconnectors.framework.common.objects.Attribute;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.quartz.JobExecutionException;
@@ -67,6 +62,12 @@ public class RealmPullResultHandlerImpl
         implements SyncopePullResultHandler {
 
     @Autowired
+    private PullUtils pullUtils;
+
+    @Autowired
+    private ConnObjectUtils connObjectUtils;
+
+    @Autowired
     private AnySearchDAO searchDAO;
 
     private SyncopePullExecutor executor;
@@ -125,24 +126,32 @@ public class RealmPullResultHandlerImpl
         }
     }
 
-    private ProvisioningReport assign(final SyncDelta delta, final String name) throws JobExecutionException {
+    private List<ProvisioningReport> assign(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
         if (!profile.getTask().isPerformCreate()) {
             LOG.debug("PullTask not configured for create");
-            return null;
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        RealmTO realmTO = new RealmTO();
-        realmTO.setName(name);
+        RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+        if (realmTO.getFullPath() == null) {
+            if (realmTO.getParent() == null) {
+                realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+            }
+
+            realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+        }
         realmTO.getResources().add(profile.getTask().getResource().getKey());
 
         ProvisioningReport result = new ProvisioningReport();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(REALM_TYPE);
         result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(profile.getTask().getDestinatioRealm().getFullPath() + "/" + name);
+        result.setName(realmTO.getFullPath());
 
         if (profile.isDryRun()) {
             result.setKey(null);
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), Result.SUCCESS, null, null, delta);
         } else {
             SyncDelta actionedDelta = delta;
             for (PullActions action : profile.getActions()) {
@@ -152,27 +161,36 @@ public class RealmPullResultHandlerImpl
             create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
         }
 
-        return result;
+        return Collections.singletonList(result);
     }
 
-    private ProvisioningReport provision(final SyncDelta delta, final String name) throws JobExecutionException {
+    private List<ProvisioningReport> provision(final SyncDelta delta, final OrgUnit orgUnit)
+            throws JobExecutionException {
+
         if (!profile.getTask().isPerformCreate()) {
             LOG.debug("PullTask not configured for create");
-            return null;
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        RealmTO realmTO = new RealmTO();
-        realmTO.setName(name);
-        realmTO.getResources().add(profile.getTask().getResource().getKey());
+        RealmTO realmTO = connObjectUtils.getRealmTO(delta.getObject(), profile.getTask(), orgUnit);
+        if (realmTO.getFullPath() == null) {
+            if (realmTO.getParent() == null) {
+                realmTO.setParent(profile.getTask().getDestinatioRealm().getFullPath());
+            }
+
+            realmTO.setFullPath(realmTO.getParent() + "/" + realmTO.getName());
+        }
 
         ProvisioningReport result = new ProvisioningReport();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(REALM_TYPE);
         result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setName(profile.getTask().getDestinatioRealm().getFullPath() + "/" + name);
+        result.setName(realmTO.getFullPath());
 
         if (profile.isDryRun()) {
             result.setKey(null);
+            finalize(UnmatchingRule.toEventName(UnmatchingRule.PROVISION), Result.SUCCESS, null, null, delta);
         } else {
             SyncDelta actionedDelta = delta;
             for (PullActions action : profile.getActions()) {
@@ -182,7 +200,7 @@ public class RealmPullResultHandlerImpl
             create(realmTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
         }
 
-        return result;
+        return Collections.singletonList(result);
     }
 
     private void throwIgnoreProvisionException(final SyncDelta delta, final Exception exception)
@@ -255,293 +273,378 @@ public class RealmPullResultHandlerImpl
         finalize(operation, resultStatus, null, output, delta);
     }
 
-    private ProvisioningReport update(final SyncDelta delta, final Realm realm, final String name)
+    private List<ProvisioningReport> update(final SyncDelta delta, final List<String> keys)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(MatchingRule.toEventName(MatchingRule.UPDATE), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to update {}", realm);
-
-        RealmTO before = binder.getRealmTO(realm, true);
-
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.UPDATE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        LOG.debug("About to update {}", keys);
 
-        Result resultStatus;
-        Object output;
-        if (!profile.isDryRun()) {
-            try {
-                before.setName(name);
+        List<ProvisioningReport> results = new ArrayList<>();
 
-                PropagationByResource propByRes = binder.update(realm, before);
-                Realm updated = realmDAO.save(realm);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to update {}", key);
 
-                List<PropagationTask> tasks = propagationManager.createTasks(updated, propByRes, null);
-                PropagationReporter propagationReporter = taskExecutor.execute(tasks, false);
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.UPDATE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-                output = updated;
-                resultStatus = Result.SUCCESS;
-                result.setName(updated.getFullPath());
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                LOG.debug("{} successfully updated", updated);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
+            if (!profile.isDryRun()) {
+                Result resultStatus;
+                Object output;
 
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
+                } else {
+                    try {
+                        for (PullActions action : profile.getActions()) {
+                            workingDelta = action.beforeUpdate(profile, workingDelta, before, null);
+                        }
+
+                        PropagationByResource propByRes = binder.update(realm, before);
+                        realm = realmDAO.save(realm);
+                        RealmTO updated = binder.getRealmTO(realm, true);
+
+                        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+                        taskExecutor.execute(tasks, false);
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, updated, result);
+                        }
+
+                        output = updated;
+                        resultStatus = Result.SUCCESS;
+                        result.setName(updated.getFullPath());
+
+                        LOG.debug("{} successfully updated", updated);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
+                }
+                finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
             }
-            finalize(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport deprovision(final SyncDelta delta, final Realm realm, final boolean unlink)
+    private List<ProvisioningReport> deprovision(final SyncDelta delta, final List<String> keys, final boolean unlink)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(unlink
+                    ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+                    : MatchingRule.toEventName(MatchingRule.DEPROVISION), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to deprovision {}", realm);
+        LOG.debug("About to deprovision {}", keys);
 
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.DELETE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        final List<ProvisioningReport> results = new ArrayList<>();
 
-        RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to unassign resource {}", key);
 
-        Object output;
-        Result resultStatus;
-        if (!profile.isDryRun()) {
-            result.setName(realm.getFullPath());
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.DELETE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-            try {
-                if (unlink) {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeUnassign(profile, delta, before);
-                    }
-                } else {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeDeprovision(profile, delta, before);
-                    }
-                }
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                PropagationByResource propByRes = new PropagationByResource();
-                propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
-                taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+            if (!profile.isDryRun()) {
+                Object output;
+                Result resultStatus;
 
-                if (unlink) {
-                    realm.getResources().remove(profile.getTask().getResource());
-                    output = binder.getRealmTO(realmDAO.save(realm), true);
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
                 } else {
-                    output = binder.getRealmTO(realm, true);
-                }
-
-                for (PullActions action : profile.getActions()) {
-                    action.after(profile, delta, RealmTO.class.cast(output), result);
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeUnassign(profile, workingDelta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeDeprovision(profile, workingDelta, before);
+                            }
+                        }
+
+                        PropagationByResource propByRes = new PropagationByResource();
+                        propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+                        taskExecutor.execute(propagationManager.createTasks(realm, propByRes, null), false);
+
+                        if (unlink) {
+                            realm.getResources().remove(profile.getTask().getResource());
+                            output = binder.getRealmTO(realmDAO.save(realm), true);
+                        } else {
+                            output = binder.getRealmTO(realm, true);
+                        }
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, RealmTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+
+                        LOG.debug("{} successfully updated", realm);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
                 }
-
-                resultStatus = Result.SUCCESS;
-
-                LOG.debug("{} successfully updated", realm);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
-
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                finalize(unlink
+                        ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+                        : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
             }
-
-            finalize(unlink
-                    ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
-                    : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport link(final SyncDelta delta, final Realm realm, final boolean unlink)
+    private List<ProvisioningReport> link(final SyncDelta delta, final List<String> keys, final boolean unlink)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("PullTask not configured for update");
-            return null;
+            finalize(unlink
+                    ? MatchingRule.toEventName(MatchingRule.UNLINK)
+                    : MatchingRule.toEventName(MatchingRule.LINK), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to link {}", realm);
+        LOG.debug("About to link {}", keys);
 
-        ProvisioningReport result = new ProvisioningReport();
-        result.setOperation(ResourceOperation.NONE);
-        result.setAnyType(REALM_TYPE);
-        result.setStatus(ProvisioningReport.Status.SUCCESS);
-        result.setKey(realm.getKey());
+        final List<ProvisioningReport> results = new ArrayList<>();
 
-        RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            LOG.debug("About to unassign resource {}", key);
 
-        Object output;
-        Result resultStatus;
-        if (!profile.isDryRun()) {
-            result.setName(realm.getFullPath());
+            ProvisioningReport result = new ProvisioningReport();
+            result.setOperation(ResourceOperation.NONE);
+            result.setAnyType(REALM_TYPE);
+            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            result.setKey(key);
 
-            try {
-                if (unlink) {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeUnlink(profile, delta, before);
-                    }
-                } else {
-                    for (PullActions action : profile.getActions()) {
-                        action.beforeLink(profile, delta, before);
-                    }
-                }
+            Realm realm = realmDAO.find(key);
+            RealmTO before = binder.getRealmTO(realm, true);
+            if (before == null) {
+                result.setStatus(ProvisioningReport.Status.FAILURE);
+                result.setMessage(String.format("Realm '%s' not found", key));
+            } else {
+                result.setName(before.getFullPath());
+            }
 
-                if (unlink) {
-                    realm.getResources().remove(profile.getTask().getResource());
+            Object output;
+            Result resultStatus;
+            if (!profile.isDryRun()) {
+                if (before == null) {
+                    resultStatus = Result.FAILURE;
+                    output = null;
                 } else {
-                    realm.add(profile.getTask().getResource());
-                }
-                output = update(delta, realm, realm.getName());
-
-                for (PullActions action : profile.getActions()) {
-                    action.after(profile, delta, RealmTO.class.cast(output), result);
+                    try {
+                        if (unlink) {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeUnlink(profile, workingDelta, before);
+                            }
+                        } else {
+                            for (PullActions action : profile.getActions()) {
+                                workingDelta = action.beforeLink(profile, workingDelta, before);
+                            }
+                        }
+
+                        if (unlink) {
+                            realm.getResources().remove(profile.getTask().getResource());
+                        } else {
+                            realm.add(profile.getTask().getResource());
+                        }
+                        output = update(workingDelta, Collections.singletonList(key));
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, RealmTO.class.cast(output), result);
+                        }
+
+                        resultStatus = Result.SUCCESS;
+
+                        LOG.debug("{} successfully updated", realm);
+                    } catch (PropagationException e) {
+                        // A propagation failure doesn't imply a pull failure.
+                        // The propagation exception status will be reported into the propagation task execution.
+                        LOG.error("Could not propagate Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not update Realm {}", workingDelta.getUid().getUidValue(), e);
+                        output = e;
+                        resultStatus = Result.FAILURE;
+                    }
                 }
-
-                resultStatus = Result.SUCCESS;
-
-                LOG.debug("{} successfully updated", realm);
-            } catch (PropagationException e) {
-                // A propagation failure doesn't imply a pull failure.
-                // The propagation exception status will be reported into the propagation task execution.
-                LOG.error("Could not propagate Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
-            } catch (Exception e) {
-                throwIgnoreProvisionException(delta, e);
-
-                result.setStatus(ProvisioningReport.Status.FAILURE);
-                result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                LOG.error("Could not update Realm {}", delta.getUid().getUidValue(), e);
-                output = e;
-                resultStatus = Result.FAILURE;
+                finalize(unlink
+                        ? MatchingRule.toEventName(MatchingRule.UNLINK)
+                        : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, workingDelta);
             }
-
-            finalize(unlink
-                    ? MatchingRule.toEventName(MatchingRule.UNLINK)
-                    : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
+            results.add(result);
         }
 
-        return result;
+        return results;
     }
 
-    private ProvisioningReport delete(final SyncDelta delta, final Realm realm)
+    private List<ProvisioningReport> delete(final SyncDelta delta, final List<String> keys)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformDelete()) {
             LOG.debug("PullTask not configured for delete");
-            return null;
+            finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
+            return Collections.<ProvisioningReport>emptyList();
         }
 
-        LOG.debug("About to delete {}", realm);
+        LOG.debug("About to delete {}", keys);
 
-        SyncDelta workingDelta = delta;
-        Object output;
-        Result resultStatus = Result.FAILURE;
+        List<ProvisioningReport> results = new ArrayList<>();
 
-        ProvisioningReport result = new ProvisioningReport();
-
-        try {
-            RealmTO before = binder.getRealmTO(realm, true);
+        SyncDelta workingDelta = delta;
+        for (String key : keys) {
+            Object output;
+            Result resultStatus = Result.FAILURE;
 
-            result.setKey(realm.getKey());
-            result.setName(realm.getFullPath());
-            result.setOperation(ResourceOperation.DELETE);
-            result.setAnyType(REALM_TYPE);
-            result.setStatus(ProvisioningReport.Status.SUCCESS);
+            ProvisioningReport result = new ProvisioningReport();
 
-            if (!profile.isDryRun()) {
-                for (PullActions action : profile.getActions()) {
-                    workingDelta = action.beforeDelete(profile, workingDelta, before);
+            try {
+                result.setKey(key);
+                result.setOperation(ResourceOperation.DELETE);
+                result.setAnyType(REALM_TYPE);
+                result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+                Realm realm = realmDAO.find(key);
+                RealmTO before = binder.getRealmTO(realm, true);
+                if (before == null) {
+                    result.setStatus(ProvisioningReport.Status.FAILURE);
+                    result.setMessage(String.format("Realm '%s' not found", key));
+                } else {
+                    result.setName(before.getFullPath());
                 }
 
-                try {
-                    if (!realmDAO.findChildren(realm).isEmpty()) {
-                        throw SyncopeClientException.build(ClientExceptionType.HasChildren);
-                    }
-
-                    Set<String> adminRealms = Collections.singleton(realm.getFullPath());
-                    AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
-                    keyCond.setSchema("key");
-                    SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
-                    int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
-                    int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
-                    int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
-
-                    if (users + groups + anyObjects > 0) {
-                        SyncopeClientException containedAnys = SyncopeClientException.build(
-                                ClientExceptionType.AssociatedAnys);
-                        containedAnys.getElements().add(users + " user(s)");
-                        containedAnys.getElements().add(groups + " group(s)");
-                        containedAnys.getElements().add(anyObjects + " anyObject(s)");
-                        throw containedAnys;
+                if (!profile.isDryRun()) {
+                    for (PullActions action : profile.getActions()) {
+                        workingDelta = action.beforeDelete(profile, workingDelta, before);
                     }
 
-                    PropagationByResource propByRes = new PropagationByResource();
-                    for (String resource : realm.getResourceKeys()) {
-                        propByRes.add(ResourceOperation.DELETE, resource);
+                    try {
+                        if (!realmDAO.findChildren(realm).isEmpty()) {
+                            throw SyncopeClientException.build(ClientExceptionType.HasChildren);
+                        }
+
+                        Set<String> adminRealms = Collections.singleton(realm.getFullPath());
+                        AnyCond keyCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
+                        keyCond.setSchema("key");
+                        SearchCond allMatchingCond = SearchCond.getLeafCond(keyCond);
+                        int users = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.USER);
+                        int groups = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.GROUP);
+                        int anyObjects = searchDAO.count(adminRealms, allMatchingCond, AnyTypeKind.ANY_OBJECT);
+
+                        if (users + groups + anyObjects > 0) {
+                            SyncopeClientException containedAnys = SyncopeClientException.build(
+                                    ClientExceptionType.AssociatedAnys);
+                            containedAnys.getElements().add(users + " user(s)");
+                            containedAnys.getElements().add(groups + " group(s)");
+                            containedAnys.getElements().add(anyObjects + " anyObject(s)");
+                            throw containedAnys;
+                        }
+
+                        PropagationByResource propByRes = new PropagationByResource();
+                        for (String resource : realm.getResourceKeys()) {
+                            propByRes.add(ResourceOperation.DELETE, resource);
+                        }
+                        List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
+                        taskExecutor.execute(tasks, false);
+
+                        realmDAO.delete(realm);
+
+                        output = null;
+                        resultStatus = Result.SUCCESS;
+
+                        for (PullActions action : profile.getActions()) {
+                            action.after(profile, workingDelta, before, result);
+                        }
+                    } catch (Exception e) {
+                        throwIgnoreProvisionException(workingDelta, e);
+
+                        result.setStatus(ProvisioningReport.Status.FAILURE);
+                        result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+                        LOG.error("Could not delete {}", realm, e);
+                        output = e;
                     }
-                    List<PropagationTask> tasks = propagationManager.createTasks(realm, propByRes, null);
-                    PropagationReporter propagationReporter = taskExecutor.execute(tasks, false);
-
-                    realmDAO.delete(realm);
 
-                    output = null;
-                    resultStatus = Result.SUCCESS;
-
-                    for (PullActions action : profile.getActions()) {
-                        action.after(profile, workingDelta, before, result);
-                    }
-                } catch (Exception e) {
-                    throwIgnoreProvisionException(delta, e);
-
-                    result.setStatus(ProvisioningReport.Status.FAILURE);
-                    result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                    LOG.error("Could not delete {}", realm, e);
-                    output = e;
+                    finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
                 }
 
-                finalize(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+                results.add(result);
+            } catch (DelegatedAdministrationException e) {
+                LOG.error("Not allowed to read Realm {}", key, e);
+            } catch (Exception e) {
+                LOG.error("Could not delete Realm {}", key, e);
             }
-        } catch (Exception e) {
-            LOG.error("Could not delete {}", realm, e);
         }
 
-        return result;
+        return results;
     }
 
     private ProvisioningReport ignore(
@@ -572,43 +675,46 @@ public class RealmPullResultHandlerImpl
         LOG.debug("Process {} for {} as {}",
                 delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
 
-        Realm realm = IterableUtils.find(realmDAO.findAll(), new Predicate<Realm>() {
+        String uid = delta.getPreviousUid() == null
+                ? delta.getUid().getUidValue()
+                : delta.getPreviousUid().getUidValue();
 
-            @Override
-            public boolean evaluate(final Realm realm) {
-                JexlContext jexlContext = new MapContext();
-                JexlUtils.addFieldsToContext(realm, jexlContext);
-                String evalConnObjectLink = JexlUtils.evaluate(orgUnit.getConnObjectLink(), jexlContext);
-
-                return delta.getObject().getName().getNameValue().equals(evalConnObjectLink);
-            }
-        });
+        List<String> keys = pullUtils.findExisting(uid, delta.getObject(), orgUnit);
         LOG.debug("Match found for {} as {}: {}",
-                delta.getObject().getName().getNameValue(), delta.getObject().getObjectClass(), realm);
+                delta.getUid().getUidValue(), delta.getObject().getObjectClass(), keys);
 
-        String realmName = delta.getUid().getUidValue();
-        Attribute nameAttr = delta.getObject().getAttributeByName(orgUnit.getExtAttrName());
-        if (nameAttr != null && nameAttr.getValue() != null && !nameAttr.getValue().isEmpty()) {
-            realmName = nameAttr.getValue().get(0).toString();
+        if (keys.size() > 1) {
+            switch (profile.getResAct()) {
+                case IGNORE:
+                    throw new IllegalStateException("More than one match " + keys);
+
+                case FIRSTMATCH:
+                    keys = keys.subList(0, 1);
+                    break;
+
+                case LASTMATCH:
+                    keys = keys.subList(keys.size() - 1, keys.size());
+                    break;
+
+                default:
+                // keep keys unmodified
+                }
         }
 
         try {
             if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
-                if (realm == null) {
+                if (keys.isEmpty()) {
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), assign(delta, realmName));
+                            profile.getResults().addAll(assign(delta, orgUnit));
                             break;
 
                         case PROVISION:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), provision(delta, realmName));
+                            profile.getResults().addAll(provision(delta, orgUnit));
                             break;
 
                         case IGNORE:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), ignore(delta, false));
+                            profile.getResults().add(ignore(delta, false));
                             break;
 
                         default:
@@ -617,32 +723,27 @@ public class RealmPullResultHandlerImpl
                 } else {
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), update(delta, realm, realmName));
+                            profile.getResults().addAll(update(delta, keys));
                             break;
 
                         case DEPROVISION:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), deprovision(delta, realm, false));
+                            profile.getResults().addAll(deprovision(delta, keys, false));
                             break;
 
                         case UNASSIGN:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), deprovision(delta, realm, true));
+                            profile.getResults().addAll(deprovision(delta, keys, true));
                             break;
 
                         case LINK:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), link(delta, realm, false));
+                            profile.getResults().addAll(link(delta, keys, false));
                             break;
 
                         case UNLINK:
-                            CollectionUtils.addIgnoreNull(
-                                    profile.getResults(), link(delta, realm, true));
+                            profile.getResults().addAll(link(delta, keys, true));
                             break;
 
                         case IGNORE:
-                            CollectionUtils.addIgnoreNull(profile.getResults(), ignore(delta, true));
+                            profile.getResults().add(ignore(delta, true));
                             break;
 
                         default:
@@ -650,10 +751,11 @@ public class RealmPullResultHandlerImpl
                     }
                 }
             } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
-                if (realm == null) {
+                if (keys.isEmpty()) {
+                    finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, delta);
                     LOG.debug("No match found for deletion");
                 } else {
-                    CollectionUtils.addIgnoreNull(profile.getResults(), delete(delta, realm));
+                    profile.getResults().addAll(delete(delta, keys));
                 }
             }
         } catch (IllegalStateException | IllegalArgumentException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
index f028b38..104276e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/RealmPushResultHandlerImpl.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.AuditElements;
@@ -32,9 +33,10 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -44,10 +46,9 @@ import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
 import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler;
 import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@@ -59,7 +60,10 @@ public class RealmPushResultHandlerImpl
         implements SyncopePushResultHandler {
 
     @Autowired
-    protected SchedulerFactoryBean scheduler;
+    private MappingManager mappingManager;
+
+    @Autowired
+    private SchedulerFactoryBean scheduler;
 
     @Transactional(propagation = Propagation.REQUIRES_NEW)
     @Override
@@ -153,39 +157,22 @@ public class RealmPushResultHandlerImpl
         provision(update(realmTO, result), result);
     }
 
-    /**
-     * Get remote object for given realm .
-     *
-     * @param connector connector facade proxy.
-     * @param task current propagation task.
-     * @param orgUnit orgUnit
-     * @return remote connector object.
-     */
-    private ConnectorObject getRemoteObject(
-            final String realmName,
-            final Connector connector,
-            final OrgUnit orgUnit) {
-
-        final ConnectorObject[] obj = new ConnectorObject[1];
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+        ConnectorObject obj = null;
         try {
-            connector.search(orgUnit.getObjectClass(),
-                    new EqualsFilter(AttributeBuilder.build(orgUnit.getExtAttrName(), realmName)),
-                    new ResultsHandler() {
-
-                @Override
-                public boolean handle(final ConnectorObject connectorObject) {
-                    obj[0] = connectorObject;
-                    return false;
-                }
-            }, MappingUtils.buildOperationOptions(orgUnit));
+            Uid uid = new Uid(connObjectKey);
+
+            obj = profile.getConnector().getObject(objectClass,
+                    uid,
+                    MappingUtils.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", realmName, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
 
-        return obj[0];
+        return obj;
     }
 
     private void doHandle(final Realm realm) throws JobExecutionException {
@@ -202,10 +189,10 @@ public class RealmPushResultHandlerImpl
         Result resultStatus = null;
 
         // Try to read remote object BEFORE any actual operation
-        ConnectorObject beforeObj = getRemoteObject(
-                realm.getName(),
-                profile.getConnector(),
-                profile.getTask().getResource().getOrgUnit());
+        OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit();
+        String connObjecKey = mappingManager.getConnObjectKeyValue(realm, orgUnit);
+
+        ConnectorObject beforeObj = getRemoteObject(connObjecKey, orgUnit.getObjectClass());
 
         if (profile.isDryRun()) {
             if (beforeObj == null) {
@@ -375,10 +362,7 @@ public class RealmPushResultHandlerImpl
                     result.setStatus(ProvisioningReport.Status.SUCCESS);
                 }
                 resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(
-                        realm.getName(),
-                        profile.getConnector(),
-                        profile.getTask().getResource().getOrgUnit());
+                output = getRemoteObject(connObjecKey, orgUnit.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
index be35d61..249e488 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -29,6 +29,7 @@ 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.RealmTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -41,6 +42,8 @@ import org.apache.syncope.core.spring.security.PasswordGenerator;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.MappingManager;
@@ -159,6 +162,16 @@ public class ConnObjectUtils {
         return anyTO;
     }
 
+    public RealmTO getRealmTO(final ConnectorObject obj, final PullTask task, final OrgUnit orgUnit) {
+        RealmTO realmTO = new RealmTO();
+
+        for (OrgUnitItem item : MappingUtils.getPullItems(orgUnit)) {
+            mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), realmTO);
+        }
+
+        return realmTO;
+    }
+
     /**
      * Build {@link AnyPatch} out of connector object attributes and schema mapping.
      *
@@ -255,7 +268,7 @@ public class ConnObjectUtils {
 
         // 1. fill with data from connector object
         anyTO.setRealm(pullTask.getDestinatioRealm().getFullPath());
-        for (MappingItem item : MappingUtils.getPullMappingItems(provision)) {
+        for (MappingItem item : MappingUtils.getPullItems(provision)) {
             mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index e719a38..2c71f37 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -19,25 +19,27 @@
 package org.apache.syncope.core.provisioning.java.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.collections4.Predicate;
 import org.apache.commons.jexl3.JexlContext;
 import org.apache.commons.jexl3.MapContext;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.Item;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
+import org.apache.syncope.core.persistence.api.entity.resource.OrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.JEXLMappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
+import org.apache.syncope.core.provisioning.java.data.JEXLItemTransformerImpl;
 import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.identityconnectors.framework.common.objects.Name;
@@ -48,6 +50,8 @@ import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.JEXLItemTransformer;
 
 public final class MappingUtils {
 
@@ -64,67 +68,68 @@ public final class MappingUtils {
                 : 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();
-        }
+    public static List<? extends MappingItem> getPropagationItems(final Provision provision) {
+        return ListUtils.select(provision.getMapping().getItems(), new Predicate<MappingItem>() {
 
-        List<MappingItem> result = new ArrayList<>();
-
-        switch (purpose) {
-            case PULL:
-                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.PULL != 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:
-        }
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.getPurpose() == MappingPurpose.PROPAGATION || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
+    }
 
-        return result;
+    public static List<? extends MappingItem> getPullItems(final Provision provision) {
+        return ListUtils.select(provision.getMapping().getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.getPurpose() == MappingPurpose.PULL || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
     }
 
-    public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.PROPAGATION);
+    public static List<? extends OrgUnitItem> getPropagationItems(final OrgUnit orgUnit) {
+        return ListUtils.select(orgUnit.getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.getPurpose() == MappingPurpose.PROPAGATION || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
     }
 
-    public static List<MappingItem> getPullMappingItems(final Provision provision) {
-        return getMappingItems(provision, MappingPurpose.PULL);
+    public static List<? extends OrgUnitItem> getPullItems(final OrgUnit orgUnit) {
+        return ListUtils.select(orgUnit.getItems(), new Predicate<OrgUnitItem>() {
+
+            @Override
+            public boolean evaluate(final OrgUnitItem item) {
+                return item.getPurpose() == MappingPurpose.PULL || item.getPurpose() == MappingPurpose.BOTH;
+            }
+        });
+    }
+
+    private static Name evaluateNAME(final String evalConnObjectLink, final String connObjectKey) {
+        // 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;
     }
 
     /**
-     * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
+     * Build __NAME__ for propagation.
+     * First look if there is a defined connObjectLink for the given resource (and in
      * this case evaluate as JEXL); otherwise, take given connObjectKey.
      *
      * @param any given any object
@@ -151,36 +156,51 @@ public final class MappingUtils {
             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);
+        return evaluateNAME(evalConnObjectLink, connObjectKey);
+    }
 
-            // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
-            LOG.debug("connObjectKey will be used just as __UID__ attribute");
+    /**
+     * Build __NAME__ for propagation.
+     * First look if there is a defined connObjectLink for the given resource (and in
+     * this case evaluate as JEXL); otherwise, take given connObjectKey.
+     *
+     * @param realm given any object
+     * @param orgUnit external resource
+     * @param connObjectKey connector object key
+     * @return the value to be propagated as __NAME__
+     */
+    public static Name evaluateNAME(final Realm realm, final OrgUnit orgUnit, 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 '{}': ", orgUnit.getResource());
         }
 
-        return name;
+        // Evaluate connObjectKey expression
+        String connObjectLink = orgUnit == null
+                ? null
+                : orgUnit.getConnObjectLink();
+        String evalConnObjectLink = null;
+        if (StringUtils.isNotBlank(connObjectLink)) {
+            JexlContext jexlContext = new MapContext();
+            JexlUtils.addFieldsToContext(realm, jexlContext);
+            evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
+        }
+
+        return evaluateNAME(evalConnObjectLink, connObjectKey);
     }
 
-    private static List<MappingItemTransformer> getMappingItemTransformers(
+    private static List<ItemTransformer> getMappingItemTransformers(
             final String propagationJEXLTransformer,
             final String pullJEXLTransformer,
             final List<String> mappingItemTransformerClassNames) {
 
-        List<MappingItemTransformer> result = new ArrayList<>();
+        List<ItemTransformer> result = new ArrayList<>();
 
         // First consider the JEXL transformation expressions
         if (StringUtils.isNotBlank(propagationJEXLTransformer) || StringUtils.isNotBlank(pullJEXLTransformer)) {
-            JEXLMappingItemTransformer jexlTransformer =
-                    (JEXLMappingItemTransformer) ApplicationContextProvider.getBeanFactory().
-                            createBean(JEXLMappingItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME,
+            JEXLItemTransformer jexlTransformer =
+                    (JEXLItemTransformer) ApplicationContextProvider.getBeanFactory().
+                            createBean(JEXLItemTransformerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME,
                                     false);
 
             jexlTransformer.setPropagationJEXL(propagationJEXLTransformer);
@@ -193,7 +213,7 @@ public final class MappingUtils {
             try {
                 Class<?> transformerClass = ClassUtils.getClass(className);
 
-                result.add((MappingItemTransformer) ApplicationContextProvider.getBeanFactory().
+                result.add((ItemTransformer) ApplicationContextProvider.getBeanFactory().
                         createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
             } catch (Exception e) {
                 LOG.error("Could not instantiate {}, ignoring...", className, e);
@@ -203,28 +223,28 @@ public final class MappingUtils {
         return result;
     }
 
-    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItemTO mappingItem) {
+    public static List<ItemTransformer> getItemTransformers(final ItemTO item) {
         return getMappingItemTransformers(
-                mappingItem.getPropagationJEXLTransformer(),
-                mappingItem.getPullJEXLTransformer(),
-                mappingItem.getMappingItemTransformerClassNames());
+                item.getPropagationJEXLTransformer(),
+                item.getPullJEXLTransformer(),
+                item.getTransformerClassNames());
     }
 
-    public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
+    public static List<ItemTransformer> getItemTransformers(final Item item) {
         return getMappingItemTransformers(
-                mappingItem.getPropagationJEXLTransformer(),
-                mappingItem.getPullJEXLTransformer(),
-                mappingItem.getMappingItemTransformerClassNames());
+                item.getPropagationJEXLTransformer(),
+                item.getPullJEXLTransformer(),
+                item.getTransformerClassNames());
     }
 
     /**
      * Build options for requesting all mapped connector attributes.
      *
-     * @param mapItems mapping items
+     * @param iterator items
      * @return options for requesting all mapped connector attributes
      * @see OperationOptions
      */
-    public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
+    public static OperationOptions buildOperationOptions(final Iterator<? extends Item> iterator) {
         OperationOptionsBuilder builder = new OperationOptionsBuilder();
 
         Set<String> attrsToGet = new HashSet<>();
@@ -232,10 +252,10 @@ public final class MappingUtils {
         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());
+        while (iterator.hasNext()) {
+            Item item = iterator.next();
+            if (item.getPurpose() != MappingPurpose.NONE) {
+                attrsToGet.add(item.getExtAttrName());
             }
         }
 
@@ -246,17 +266,6 @@ public final class MappingUtils {
     }
 
     /**
-     * Build options for requesting connector attributes for the given orgUnit.
-     *
-     * @param orgUnit orgUnit
-     * @return options for requesting connector attributes for the given orgUnit
-     * @see OperationOptions
-     */
-    public static OperationOptions buildOperationOptions(final OrgUnit orgUnit) {
-        return new OperationOptionsBuilder().setAttributesToGet(Name.NAME, Uid.NAME, orgUnit.getExtAttrName()).build();
-    }
-
-    /**
      * Private default constructor, for static-only classes.
      */
     private MappingUtils() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
index 714dcff..bc7329a 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ResourceDataBinderTest.java
@@ -28,7 +28,7 @@ import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -122,7 +122,7 @@ public class ResourceDataBinderTest extends AbstractTest {
         MappingTO mapping = new MappingTO();
         provisionTO.setMapping(mapping);
 
-        MappingItemTO item = new MappingItemTO();
+        ItemTO item = new ItemTO();
         item.setIntAttrName("userId");
         item.setExtAttrName("campo1");
         item.setConnObjectKey(true);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
index 2597f42..8ea1671 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPMappingPanel.java
@@ -23,9 +23,9 @@ import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -40,13 +40,13 @@ public class SAML2IdPMappingPanel extends AbstractMappingPanel {
     public SAML2IdPMappingPanel(
             final String id,
             final SAML2IdPTO idpTO,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ItemTransformersTogglePanel mapItemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
         super(id,
                 mapItemTransformers,
                 jexlTransformers,
-                new ListModel<MappingItemTO>(idpTO.getMappingItems()),
+                new ListModel<ItemTO>(idpTO.getMappingItems()),
                 true,
                 true,
                 MappingPurpose.NONE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index d824807..aa9ea0f 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -32,8 +32,8 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
-import org.apache.syncope.client.console.wizards.resources.MappingItemTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.client.console.wizards.resources.ItemTransformersTogglePanel;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.wicket.Component;
@@ -68,8 +68,8 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
         Mapping mapping = new Mapping(modelObject);
         mapping.setOutputMarkupId(true);
 
-        MappingItemTransformersTogglePanel mapItemTransformers =
-                new MappingItemTransformersTogglePanel(mapping, pageRef);
+        ItemTransformersTogglePanel mapItemTransformers =
+                new ItemTransformersTogglePanel(mapping, pageRef);
         addOuterObject(mapItemTransformers);
         JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
         addOuterObject(jexlTransformers);
@@ -133,10 +133,10 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
     @Override
     protected Serializable onApplyInternal(final SAML2IdPTO modelObject) {
         long connObjectKeyCount = IterableUtils.countMatches(
-                modelObject.getMappingItems(), new Predicate<MappingItemTO>() {
+                modelObject.getMappingItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
index 109af15..089908e 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
@@ -51,7 +51,7 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
 
     private boolean logoutSupported;
 
-    private final List<MappingItemTO> mappingItems = new ArrayList<>();
+    private final List<ItemTO> mappingItems = new ArrayList<>();
 
     @Override
     public String getKey() {
@@ -112,24 +112,24 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
         this.logoutSupported = logoutSupported;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
-        return IterableUtils.find(getMappingItems(), new Predicate<MappingItemTO>() {
+    public ItemTO getConnObjectKeyItem() {
+        return IterableUtils.find(getMappingItems(), new Predicate<ItemTO>() {
 
             @Override
-            public boolean evaluate(final MappingItemTO item) {
+            public boolean evaluate(final ItemTO item) {
                 return item.isConnObjectKey();
             }
         });
     }
 
-    protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
+    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
         connObjectItem.setMandatoryCondition("true");
         connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);
     }
 
-    public boolean setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         return connObjectKeyItem == null
                 ? remove(getConnObjectKeyItem())
                 : addConnObjectKeyItem(connObjectKeyItem);
@@ -138,15 +138,15 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO {
     @XmlElementWrapper(name = "mappingItems")
     @XmlElement(name = "mappingItem")
     @JsonProperty("mappingItems")
-    public List<MappingItemTO> getMappingItems() {
+    public List<ItemTO> getMappingItems() {
         return mappingItems;
     }
 
-    public boolean add(final MappingItemTO item) {
+    public boolean add(final ItemTO item) {
         return item == null ? false : this.mappingItems.contains(item) || this.mappingItems.add(item);
     }
 
-    public boolean remove(final MappingItemTO item) {
+    public boolean remove(final ItemTO item) {
         return this.mappingItems.remove(item);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
index bbd170d..f86b633 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
@@ -30,7 +30,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
@@ -154,7 +154,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
                 idpTO.setMetadata(Base64.getEncoder().encodeToString(baos.toByteArray()));
             }
 
-            MappingItemTO connObjectKeyItem = new MappingItemTO();
+            ItemTO connObjectKeyItem = new ItemTO();
             connObjectKeyItem.setIntAttrName("username");
             connObjectKeyItem.setExtAttrName("NameID");
             idpTO.setConnObjectKeyItem(connObjectKeyItem);

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 91e9ff0..59d6c2c 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -43,7 +43,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.SAML2RequestTO;
 import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -66,7 +66,6 @@ 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.IntAttrName;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
 import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
 import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
@@ -119,6 +118,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.stereotype.Component;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 @Component
 public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
@@ -340,11 +340,11 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         return requestTO;
     }
 
-    private List<String> findMatchingUser(final String keyValue, final MappingItemTO connObjectKeyItem) {
+    private List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
         List<String> result = new ArrayList<>();
 
         String transformed = keyValue;
-        for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(connObjectKeyItem)) {
+        for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
             List<Object> output = transformer.beforePull(
                     null,
                     null,

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
index a5ab6c3..ed244d0 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
@@ -28,7 +28,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import net.shibboleth.utilities.java.support.xml.XMLParserException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.core.logic.init.SAML2SPLoader;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
@@ -66,7 +66,7 @@ public class SAML2IdPCache {
 
     public SAML2IdPEntity put(
             final EntityDescriptor entityDescriptor,
-            final MappingItemTO connObjectKeyItem,
+            final ItemTO connObjectKeyItem,
             final boolean useDeflateEncoding,
             final SAML2BindingType bindingType)
             throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
index 6b75472..c060e58 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java
@@ -31,7 +31,7 @@ import java.util.Base64;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.saml2.metadata.Endpoint;
@@ -55,7 +55,7 @@ public class SAML2IdPEntity {
 
     private SAML2BindingType bindingType;
 
-    private MappingItemTO connObjectKeyItem;
+    private ItemTO connObjectKeyItem;
 
     private final Map<String, Endpoint> ssoBindings = new HashMap<>();
 
@@ -67,7 +67,7 @@ public class SAML2IdPEntity {
 
     public SAML2IdPEntity(
             final EntityDescriptor entityDescriptor,
-            final MappingItemTO connObjectKeyItem,
+            final ItemTO connObjectKeyItem,
             final boolean useDeflateEncoding,
             final SAML2BindingType bindingType,
             final String keyPass)
@@ -142,11 +142,11 @@ public class SAML2IdPEntity {
         this.bindingType = bindingType;
     }
 
-    public MappingItemTO getConnObjectKeyItem() {
+    public ItemTO getConnObjectKeyItem() {
         return connObjectKeyItem;
     }
 
-    public void setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+    public void setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
         this.connObjectKeyItem = connObjectKeyItem;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
index 9869500..3e80bed 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java
@@ -24,7 +24,7 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 
 public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP> {
 
@@ -61,12 +61,12 @@ public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP
         }
 
         for (MappingItem item : value.getMappingItems()) {
-            for (String className : item.getMappingItemTransformerClassNames()) {
+            for (String className : item.getTransformerClassNames()) {
                 Class<?> actionsClass = null;
                 boolean isAssignable = false;
                 try {
                     actionsClass = Class.forName(className);
-                    isAssignable = MappingItemTransformer.class.isAssignableFrom(actionsClass);
+                    isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass);
                 } catch (Exception e) {
                     LOG.error("Invalid MappingItemTransformer specified: {}", className, e);
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/eebca673/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
index 5eba217..f9f16ab 100644
--- a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
+++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java
@@ -22,7 +22,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.SAML2IdPTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -87,10 +87,10 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
         SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
                 ClientExceptionType.RequiredValuesMissing);
 
-        for (MappingItemTO itemTO : idpTO.getMappingItems()) {
+        for (ItemTO itemTO : idpTO.getMappingItems()) {
             if (itemTO == null) {
-                LOG.error("Null {}", MappingItemTO.class.getSimpleName());
-                invalidMapping.getElements().add("Null " + MappingItemTO.class.getSimpleName());
+                LOG.error("Null {}", ItemTO.class.getSimpleName());
+                invalidMapping.getElements().add("Null " + ItemTO.class.getSimpleName());
             } else if (itemTO.getIntAttrName() == null) {
                 requiredValuesMissing.getElements().add("intAttrName");
                 scce.addException(requiredValuesMissing);
@@ -194,7 +194,7 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
 
     private void populateMappingTO(final SAML2IdP idp, final SAML2IdPTO idpTO) {
         for (MappingItem item : idp.getMappingItems()) {
-            MappingItemTO itemTO = new MappingItemTO();
+            ItemTO itemTO = new ItemTO();
             itemTO.setKey(item.getKey());
             BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
             itemTO.setPurpose(MappingPurpose.NONE);


[05/12] syncope git commit: [SYNCOPE-1164] Realm provisioning now features complete mapping, as Anys

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
index 37abe22..e13d6bb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
@@ -37,6 +37,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
@@ -52,7 +53,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
-public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
+public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision> {
 
     private static final long serialVersionUID = 3739399543837732640L;
 
@@ -76,13 +77,18 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
                 }
             }, currentlyAdded);
 
-            return ListUtils.select(new AnyTypeRestClient().list(), new Predicate<String>() {
+            List<String> result = ListUtils.select(new AnyTypeRestClient().list(), new Predicate<String>() {
 
                 @Override
                 public boolean evaluate(final String key) {
                     return !currentlyAdded.contains(key);
                 }
             });
+            if (resourceTO.getOrgUnit() == null) {
+                result.add(0, SyncopeConstants.REALM_ANYTYPE);
+            }
+
+            return result;
         }
     };
 
@@ -93,7 +99,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = -1657800545799468278L;
 
-        ObjectType(final ProvisionTO item) {
+        ObjectType(final ResourceProvision item) {
             super(new ResourceModel("type.title", StringUtils.EMPTY),
                     new ResourceModel("type.summary", StringUtils.EMPTY), new Model<>(item));
 
@@ -135,14 +141,23 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
     /**
      * AuxClasses definition step.
      */
-    private static final class AuxClasses extends WizardStep {
+    private static final class AuxClasses extends WizardStep implements WizardModel.ICondition {
 
         private static final long serialVersionUID = 5315236191866427500L;
 
-        AuxClasses(final ProvisionTO item) {
+        private final ResourceProvision provision;
+
+        AuxClasses(final ResourceProvision item) {
+            this.provision = item;
+
             setTitleModel(new ResourceModel("auxClasses.title"));
             setSummaryModel(new StringResourceModel("auxClasses.summary", this, new Model<>(item)));
-            add(new ProvisionAuxClassesPanel("auxClasses", item));
+            add(new ProvisionAuxClassesPanel("auxClasses", item.getProvisionTO()));
+        }
+
+        @Override
+        public boolean evaluate() {
+            return provision.getProvisionTO() != null;
         }
     }
 
@@ -153,7 +168,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = 3454904947720856253L;
 
-        Mapping(final ProvisionTO item) {
+        Mapping(final ResourceProvision item) {
             setTitleModel(Model.of("Mapping"));
             setSummaryModel(Model.of(StringUtils.EMPTY));
         }
@@ -166,7 +181,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
 
         private static final long serialVersionUID = 2359955465172450478L;
 
-        ConnObjectLink(final ProvisionTO item) {
+        ConnObjectLink(final ResourceProvision item) {
             super(new ResourceModel("link.title", StringUtils.EMPTY),
                     new ResourceModel("link.summary", StringUtils.EMPTY));
 
@@ -175,7 +190,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
             add(connObjectLinkContainer);
 
             boolean connObjectLinkEnabled = false;
-            if (StringUtils.isNotBlank(item.getMapping().getConnObjectLink())) {
+            if (StringUtils.isNotBlank(item.getConnObjectLink())) {
                 connObjectLinkEnabled = true;
             }
 
@@ -191,8 +206,9 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
             final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel(
                     "connObjectLink",
                     new ResourceModel("connObjectLink", "connObjectLink").getObject(),
-                    new PropertyModel<String>(item.getMapping(), "connObjectLink"),
+                    new PropertyModel<String>(item, "connObjectLink"),
                     false);
+            connObjectLink.enableJexlHelp();
             connObjectLink.setEnabled(connObjectLinkEnabled);
             connObjectLinkContainer.add(connObjectLink);
 
@@ -218,28 +234,27 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
      * @param pageRef Caller page reference.
      */
     public ProvisionWizardBuilder(final ResourceTO resurceTO, final PageReference pageRef) {
-        super(new ProvisionTO(), pageRef);
+        super(new ResourceProvision(), pageRef);
         this.resourceTO = resurceTO;
     }
 
     @Override
-    protected WizardModel buildModelSteps(final ProvisionTO modelObject, final WizardModel wizardModel) {
+    protected WizardModel buildModelSteps(final ResourceProvision modelObject, final WizardModel wizardModel) {
         wizardModel.add(new ObjectType(modelObject));
         wizardModel.add(new AuxClasses(modelObject));
 
         Mapping mapping = new Mapping(modelObject);
         mapping.setOutputMarkupId(true);
 
-        MappingItemTransformersTogglePanel mapItemTransformers =
-                new MappingItemTransformersTogglePanel(mapping, pageRef);
-        addOuterObject(mapItemTransformers);
+        ItemTransformersTogglePanel itemTransformers = new ItemTransformersTogglePanel(mapping, pageRef);
+        addOuterObject(itemTransformers);
         JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
         addOuterObject(jexlTransformers);
-        if (modelObject.getMapping() == null) {
-            modelObject.setMapping(new MappingTO());
+        if (modelObject.getProvisionTO() != null && modelObject.getProvisionTO().getMapping() == null) {
+            modelObject.getProvisionTO().setMapping(new MappingTO());
         }
         mapping.add(new ResourceMappingPanel(
-                "mapping", resourceTO, modelObject, mapItemTransformers, jexlTransformers));
+                "mapping", resourceTO, modelObject, itemTransformers, jexlTransformers));
 
         wizardModel.add(mapping);
 
@@ -248,28 +263,41 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> {
     }
 
     @Override
-    protected Serializable onApplyInternal(final ProvisionTO modelObject) {
-        final List<ProvisionTO> provisions;
-        if (modelObject.getKey() == null) {
-            provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+    protected Serializable onApplyInternal(final ResourceProvision modelObject) {
+        if (modelObject.getOrgUnitTO() != null) {
+            this.resourceTO.setOrgUnit(modelObject.getOrgUnitTO());
+
+            this.resourceTO.getOrgUnit().getItems().clear();
+            this.resourceTO.getOrgUnit().getItems().addAll(modelObject.getItems());
+        } else if (modelObject.getProvisionTO() != null) {
+            final List<ProvisionTO> provisions;
+            if (modelObject.getKey() == null) {
+                provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+
+                    @Override
+                    public boolean evaluate(final ProvisionTO object) {
+                        return !modelObject.getAnyType().equals(object.getAnyType());
+                    }
+                });
+            } else {
+                provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
 
-                @Override
-                public boolean evaluate(final ProvisionTO object) {
-                    return !modelObject.getAnyType().equals(object.getAnyType());
-                }
-            });
-        } else {
-            provisions = ListUtils.select(this.resourceTO.getProvisions(), new Predicate<ProvisionTO>() {
+                    @Override
+                    public boolean evaluate(final ProvisionTO object) {
+                        return !modelObject.getKey().equals(object.getKey());
+                    }
+                });
+            }
 
-                @Override
-                public boolean evaluate(final ProvisionTO object) {
-                    return !modelObject.getKey().equals(object.getKey());
-                }
-            });
+            ProvisionTO provisionTO = modelObject.getProvisionTO();
+            provisionTO.getMapping().getItems().clear();
+            provisionTO.getMapping().getItems().addAll(modelObject.getItems());
+            provisions.add(provisionTO);
+
+            this.resourceTO.getProvisions().clear();
+            this.resourceTO.getProvisions().addAll(provisions);
         }
-        provisions.add(modelObject);
-        this.resourceTO.getProvisions().clear();
-        this.resourceTO.getProvisions().addAll(provisions);
+
         return modelObject;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
index 93988e4..853873e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
@@ -26,10 +26,10 @@ import java.util.Set;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AbstractMappingPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.MappingItemTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -47,7 +47,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
     /**
      * External resource provisioning configuration instance to be updated.
      */
-    private final ProvisionTO provisionTO;
+    private final ResourceProvision provision;
 
     private final LoadableDetachableModel<List<String>> extAttrNames;
 
@@ -56,28 +56,28 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
      *
      * @param id panel id
      * @param resourceTO external resource to be updated
-     * @param provisionTO external resource provisioning configuration instance
-     * @param mapItemTransformers mapping item transformers toggle panel
+     * @param provision external resource provisioning configuration instance
+     * @param itemTransformers mapping item transformers toggle panel
      * @param jexlTransformers JEXL transformers toggle panel
      */
     public ResourceMappingPanel(
             final String id,
             final ResourceTO resourceTO,
-            final ProvisionTO provisionTO,
-            final MappingItemTransformersTogglePanel mapItemTransformers,
+            final ResourceProvision provision,
+            final ItemTransformersTogglePanel itemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers) {
 
         super(id,
-                mapItemTransformers,
+                itemTransformers,
                 jexlTransformers,
-                new ListModel<MappingItemTO>(provisionTO.getMapping().getItems()),
+                new ListModel<ItemTO>(provision.getItems()),
                 resourceTO.getConnector() != null,
                 false,
                 MappingPurpose.BOTH);
 
         setOutputMarkupId(true);
 
-        this.provisionTO = provisionTO;
+        this.provision = provision;
 
         extAttrNames = new LoadableDetachableModel<List<String>>() {
 
@@ -86,7 +86,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
             @Override
             protected List<String> load() {
                 return new ConnectorRestClient().getExtAttrNames(
-                        provisionTO.getObjectClass(),
+                        provision.getObjectClass(),
                         resourceTO.getConnector(),
                         resourceTO.getConfOverride());
             }
@@ -95,7 +95,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
 
     @Override
     protected boolean hidePassword() {
-        return !AnyTypeKind.USER.name().equals(provisionTO.getAnyType());
+        return !AnyTypeKind.USER.name().equals(provision.getAnyType());
     }
 
     @Override
@@ -106,7 +106,7 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
     @Override
     protected void onBeforeRender() {
         super.onBeforeRender();
-        passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provisionTO.getAnyType()));
+        passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provision.getAnyType()));
     }
 
     @Override
@@ -114,33 +114,38 @@ public class ResourceMappingPanel extends AbstractMappingPanel {
         toBeUpdated.setRequired(true);
         toBeUpdated.setEnabled(true);
 
-        AnyTypeTO anyTypeTO = anyTypeRestClient.read(provisionTO.getAnyType());
-
-        List<AnyTypeClassTO> anyTypeClassTOs = new ArrayList<>();
-        anyTypeClassTOs.addAll(anyTypeClassRestClient.list(anyTypeTO.getClasses()));
-        for (String auxClass : provisionTO.getAuxClasses()) {
-            anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass));
-        }
-
         Set<String> choices = new HashSet<>();
+        if (SyncopeConstants.REALM_ANYTYPE.equals(provision.getAnyType())) {
+            choices.add("key");
+            choices.add("name");
+            choices.add("fullpath");
+        } else {
+            AnyTypeTO anyTypeTO = anyTypeRestClient.read(provision.getAnyType());
+
+            List<AnyTypeClassTO> anyTypeClassTOs = new ArrayList<>();
+            anyTypeClassTOs.addAll(anyTypeClassRestClient.list(anyTypeTO.getClasses()));
+            for (String auxClass : provision.getAuxClasses()) {
+                anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass));
+            }
 
-        switch (provisionTO.getAnyType()) {
-            case "USER":
-                choices.addAll(USER_FIELD_NAMES);
-                break;
+            switch (provision.getAnyType()) {
+                case "USER":
+                    choices.addAll(USER_FIELD_NAMES);
+                    break;
 
-            case "GROUP":
-                choices.addAll(GROUP_FIELD_NAMES);
-                break;
+                case "GROUP":
+                    choices.addAll(GROUP_FIELD_NAMES);
+                    break;
 
-            default:
-                choices.addAll(ANY_OBJECT_FIELD_NAMES);
-        }
+                default:
+                    choices.addAll(ANY_OBJECT_FIELD_NAMES);
+            }
 
-        for (AnyTypeClassTO anyTypeClassTO : anyTypeClassTOs) {
-            choices.addAll(anyTypeClassTO.getPlainSchemas());
-            choices.addAll(anyTypeClassTO.getDerSchemas());
-            choices.addAll(anyTypeClassTO.getVirSchemas());
+            for (AnyTypeClassTO anyTypeClassTO : anyTypeClassTOs) {
+                choices.addAll(anyTypeClassTO.getPlainSchemas());
+                choices.addAll(anyTypeClassTO.getDerSchemas());
+                choices.addAll(anyTypeClassTO.getVirSchemas());
+            }
         }
 
         final List<String> names = new ArrayList<>(choices);

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
new file mode 100644
index 0000000..796fb76
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wizards.resources;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.OrgUnitTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
+
+public class ResourceProvision implements Serializable {
+
+    private static final long serialVersionUID = 1103991919577739952L;
+
+    private ProvisionTO provisionTO;
+
+    private OrgUnitTO orgUnitTO;
+
+    private List<ItemTO> items;
+
+    public ResourceProvision() {
+        this.items = new ArrayList<>();
+    }
+
+    public ResourceProvision(final ProvisionTO provisionTO) {
+        setProvisionTO(provisionTO);
+    }
+
+    public ResourceProvision(final OrgUnitTO orgUnitTO) {
+        setOrgUnitTO(orgUnitTO);
+    }
+
+    public ProvisionTO getProvisionTO() {
+        return provisionTO;
+    }
+
+    public final void setProvisionTO(final ProvisionTO provisionTO) {
+        this.provisionTO = provisionTO;
+        this.orgUnitTO = null;
+
+        if (this.items == null) {
+            this.items = new ArrayList<>();
+        } else {
+            this.items.clear();
+        }
+        if (provisionTO.getMapping() != null) {
+            this.items.addAll(provisionTO.getMapping().getItems());
+        }
+    }
+
+    public OrgUnitTO getOrgUnitTO() {
+        return orgUnitTO;
+    }
+
+    public final void setOrgUnitTO(final OrgUnitTO orgUnitTO) {
+        this.orgUnitTO = orgUnitTO;
+        this.provisionTO = null;
+
+        if (this.items == null) {
+            this.items = new ArrayList<>();
+        } else {
+            this.items.clear();
+        }
+        this.items.addAll(orgUnitTO.getItems());
+    }
+
+    public String getKey() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getKey()
+                : provisionTO.getKey();
+    }
+
+    public String getAnyType() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : SyncopeConstants.REALM_ANYTYPE : provisionTO.getAnyType();
+    }
+
+    public void setAnyType(final String anyType) {
+        if (SyncopeConstants.REALM_ANYTYPE.equals(anyType)) {
+            setOrgUnitTO(new OrgUnitTO());
+        } else {
+            setProvisionTO(new ProvisionTO());
+            getProvisionTO().setAnyType(anyType);
+            getProvisionTO().setMapping(new MappingTO());
+        }
+    }
+
+    public String getObjectClass() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getObjectClass() : provisionTO.getObjectClass();
+    }
+
+    public void setObjectClass(final String objectClass) {
+        if (provisionTO == null) {
+            orgUnitTO.setObjectClass(objectClass);
+        } else {
+            provisionTO.setObjectClass(objectClass);
+        }
+    }
+
+    public List<String> getAuxClasses() {
+        return provisionTO == null ? Collections.<String>emptyList() : provisionTO.getAuxClasses();
+    }
+
+    public String getConnObjectLink() {
+        return provisionTO == null
+                ? orgUnitTO == null
+                        ? null
+                        : orgUnitTO.getConnObjectLink()
+                : provisionTO.getMapping().getConnObjectLink();
+    }
+
+    public void setConnObjectLink(final String connObjectLink) {
+        if (provisionTO == null) {
+            orgUnitTO.setConnObjectLink(connObjectLink);
+        } else {
+            provisionTO.getMapping().setConnObjectLink(connObjectLink);
+        }
+    }
+
+    public List<ItemTO> getItems() {
+        return items;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
index 33e254a..26ce5d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
@@ -20,14 +20,12 @@ package org.apache.syncope.client.console.wizards.resources;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
@@ -36,45 +34,33 @@ import org.apache.syncope.client.console.panels.AbstractModalPanel;
 import org.apache.syncope.client.console.panels.ListViewPanel;
 import org.apache.syncope.client.console.panels.ListViewPanel.ListViewReload;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
-import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.OrgUnitTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.Broadcast;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
 
 public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
 
     private static final long serialVersionUID = -7982691107029848579L;
 
-    private final ConnectorRestClient connectorRestClient = new ConnectorRestClient();
-
     private final ResourceRestClient resourceRestClient = new ResourceRestClient();
 
     private final ResourceTO resourceTO;
 
-    private Model<OrgUnitTO> baseModel;
-
-    private final WebMarkupContainer aboutRealmProvison;
+    private final List<ResourceProvision> provisions;
 
     public ResourceProvisionPanel(
             final BaseModal<Serializable> modal,
@@ -84,108 +70,25 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
         super(modal, pageRef);
         this.resourceTO = resourceTO;
 
-        baseModel = Model.of(resourceTO.getOrgUnit() == null ? new OrgUnitTO() : resourceTO.getOrgUnit());
-
         setOutputMarkupId(true);
 
-        // ----------------------------------------------------------------------
-        // Realms provisioning
-        // ----------------------------------------------------------------------
-        aboutRealmProvison = new WebMarkupContainer("aboutRealmProvison");
-        aboutRealmProvison.setOutputMarkupPlaceholderTag(true);
-        add(aboutRealmProvison);
-
-        boolean realmProvisionEnabled = resourceTO.getOrgUnit() != null;
-
-        final AjaxCheckBoxPanel enableRealmsProvision = new AjaxCheckBoxPanel(
-                "enableRealmsProvision",
-                "enableRealmsProvision",
-                Model.of(realmProvisionEnabled),
-                false);
-        aboutRealmProvison.add(enableRealmsProvision);
-        enableRealmsProvision.setIndex(1).setTitle(getString("enableRealmsProvision.title"));
-
-        final WebMarkupContainer realmsProvisionContainer = new WebMarkupContainer("realmsProvisionContainer");
-        realmsProvisionContainer.setOutputMarkupPlaceholderTag(true);
-        realmsProvisionContainer.setEnabled(realmProvisionEnabled).setVisible(realmProvisionEnabled);
-        aboutRealmProvison.add(realmsProvisionContainer);
-
-        final AjaxTextFieldPanel objectClass = new AjaxTextFieldPanel(
-                "objectClass",
-                getString("objectClass"),
-                new PropertyModel<String>(baseModel.getObject(), "objectClass"),
-                false);
-        realmsProvisionContainer.add(objectClass.addRequiredLabel());
-
-        final AjaxTextFieldPanel extAttrName = new AjaxTextFieldPanel(
-                "extAttrName",
-                getString("extAttrName"),
-                new PropertyModel<String>(baseModel.getObject(), "extAttrName"),
-                false);
-        if (resourceTO.getOrgUnit() != null) {
-            extAttrName.setChoices(connectorRestClient.getExtAttrNames(
-                    resourceTO.getOrgUnit().getObjectClass(),
-                    resourceTO.getConnector(),
-                    resourceTO.getConfOverride()));
-        }
-        realmsProvisionContainer.add(extAttrName.addRequiredLabel());
-
-        objectClass.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                extAttrName.setChoices(connectorRestClient.getExtAttrNames(
-                        objectClass.getModelObject(),
-                        resourceTO.getConnector(),
-                        resourceTO.getConfOverride()));
-                target.focusComponent(extAttrName);
-            }
-        });
-
-        final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel(
-                "connObjectLink",
-                new ResourceModel("connObjectLink", "connObjectLink").getObject(),
-                new PropertyModel<String>(baseModel.getObject(), "connObjectLink"),
-                false);
-        realmsProvisionContainer.add(connObjectLink.addRequiredLabel());
-
-        enableRealmsProvision.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                boolean realmProvisionEnabled = enableRealmsProvision.getModelObject();
-                realmsProvisionContainer.setEnabled(realmProvisionEnabled).setVisible(realmProvisionEnabled);
-                target.add(realmsProvisionContainer);
-
-                if (realmProvisionEnabled) {
-                    resourceTO.setOrgUnit(baseModel.getObject());
-                } else {
-                    resourceTO.setOrgUnit(null);
-                }
-
-            }
-        });
-        // ----------------------------------------------------------------------
-
         final ProvisionWizardBuilder wizard = new ProvisionWizardBuilder(resourceTO, pageRef);
 
-        final ListViewPanel.Builder<ProvisionTO> builder = new ListViewPanel.Builder<ProvisionTO>(
-                ProvisionTO.class, pageRef) {
+        final ListViewPanel.Builder<ResourceProvision> builder = new ListViewPanel.Builder<ResourceProvision>(
+                ResourceProvision.class, pageRef) {
 
             private static final long serialVersionUID = 4907732721283972943L;
 
             @Override
-            protected ProvisionTO getActualItem(final ProvisionTO item, final List<ProvisionTO> list) {
+            protected ResourceProvision getActualItem(
+                    final ResourceProvision item, final List<ResourceProvision> list) {
+
                 return item == null
                         ? null
-                        : IteratorUtils.find(list.iterator(), new Predicate<ProvisionTO>() {
+                        : IteratorUtils.find(list.iterator(), new Predicate<ResourceProvision>() {
 
                             @Override
-                            public boolean evaluate(final ProvisionTO in) {
+                            public boolean evaluate(final ResourceProvision in) {
                                 return ((item.getKey() == null && in.getKey() == null)
                                         || (in.getKey() != null && in.getKey().equals(item.getKey())))
                                         && ((item.getAnyType() == null && in.getAnyType() == null)
@@ -202,45 +105,46 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
 
             @Override
             protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
-                ResourceProvisionPanel.this.aboutRealmProvison.setVisible(true);
-                target.add(ResourceProvisionPanel.this.aboutRealmProvison);
-
                 // change modal footer visibility
                 send(ResourceProvisionPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
             }
 
             @Override
             protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
-                ResourceProvisionPanel.this.aboutRealmProvison.setVisible(true);
-                target.add(ResourceProvisionPanel.this.aboutRealmProvison);
-
                 // keep list ordered - SYNCOPE-1154
-                sortProvisionList();
+                sortProvisions();
 
                 // change modal footer visibility
                 send(ResourceProvisionPanel.this, Broadcast.BUBBLE, new BaseModal.ChangeFooterVisibilityEvent(target));
             }
         };
 
+        provisions = new ArrayList<>();
+        if (resourceTO.getOrgUnit() != null) {
+            provisions.add(new ResourceProvision(resourceTO.getOrgUnit()));
+        }
+        for (ProvisionTO provision : resourceTO.getProvisions()) {
+            provisions.add(new ResourceProvision(provision));
+        }
         // keep list ordered - SYNCOPE-1154
-        sortProvisionList();
+        sortProvisions();
 
-        builder.setItems(resourceTO.getProvisions());
+        builder.setItems(provisions);
         builder.includes("anyType", "objectClass", "auxClasses");
         builder.setReuseItem(false);
 
-        builder.addAction(new ActionLink<ProvisionTO>() {
+        builder.addAction(new ActionLink<ResourceProvision>() {
 
             private static final long serialVersionUID = -3722207913631435504L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+            public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                 try {
                     send(ResourceProvisionPanel.this, Broadcast.DEPTH,
-                            new AjaxWizard.NewItemActionEvent<>(provisionTO, 2, target).setResourceModel(
+                            new AjaxWizard.NewItemActionEvent<>(provision, 2, target).setResourceModel(
                                     new StringResourceModel("inner.provision.mapping",
                                             ResourceProvisionPanel.this,
-                                            Model.of(provisionTO))));
+                                            Model.of(provision))));
                 } catch (SyncopeClientException e) {
                     LOG.error("While contacting resource", e);
                     SyncopeConsoleSession.get().error(
@@ -249,105 +153,97 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
                 }
             }
         }, ActionLink.ActionType.MAPPING, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -7780999687733432439L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                         try {
-                            resourceRestClient.setLatestSyncToken(resourceTO.getKey(), provisionTO.getAnyType());
+                            resourceRestClient.setLatestSyncToken(resourceTO.getKey(), provision.getAnyType());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                         } catch (Exception e) {
                             LOG.error("While setting latest sync token for {}/{}",
-                                    resourceTO.getKey(), provisionTO.getAnyType(), e);
+                                    resourceTO.getKey(), provision.getAnyType(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
                 }, ActionLink.ActionType.SET_LATEST_SYNC_TOKEN, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -7780999687733432439L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
                         try {
-                            resourceRestClient.removeSyncToken(resourceTO.getKey(), provisionTO.getAnyType());
+                            resourceRestClient.removeSyncToken(resourceTO.getKey(), provision.getAnyType());
                             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                         } catch (Exception e) {
                             LOG.error("While removing sync token for {}/{}",
-                                    resourceTO.getKey(), provisionTO.getAnyType(), e);
+                                    resourceTO.getKey(), provision.getAnyType(), e);
                             SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
                                     ? e.getClass().getName() : e.getMessage());
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
                 }, ActionLink.ActionType.REMOVE_SYNC_TOKEN, StandardEntitlement.RESOURCE_UPDATE).
-                addAction(new ActionLink<ProvisionTO>() {
-
-                    private static final long serialVersionUID = -3722207913631435534L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                        final ProvisionTO clone = SerializationUtils.clone(provisionTO);
-                        clone.setKey(null);
-                        clone.setAnyType(null);
-                        clone.setObjectClass(null);
-                        send(ResourceProvisionPanel.this, Broadcast.DEPTH,
-                                new AjaxWizard.NewItemActionEvent<>(clone, target).setResourceModel(
-                                        new StringResourceModel("inner.provision.clone",
-                                                ResourceProvisionPanel.this,
-                                                Model.of(provisionTO))));
-                    }
-                }, ActionLink.ActionType.CLONE, StandardEntitlement.RESOURCE_CREATE).
-                addAction(new ActionLink<ProvisionTO>() {
+                addAction(new ActionLink<ResourceProvision>() {
 
                     private static final long serialVersionUID = -3722207913631435544L;
 
                     @Override
-                    public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) {
-                        resourceTO.getProvisions().remove(provisionTO);
+                    public void onClick(final AjaxRequestTarget target, final ResourceProvision provision) {
+                        if (provision.getOrgUnitTO() != null) {
+                            resourceTO.setOrgUnit(null);
+                        } else if (provision.getProvisionTO() != null) {
+                            resourceTO.getProvisions().remove(provision.getProvisionTO());
+                        }
+                        provisions.remove(provision);
                         send(ResourceProvisionPanel.this, Broadcast.DEPTH, new ListViewReload<>(target));
                     }
-                }, ActionLink.ActionType.DELETE, StandardEntitlement.RESOURCE_DELETE);
+                }, ActionLink.ActionType.DELETE, StandardEntitlement.RESOURCE_UPDATE);
 
         builder.addNewItemPanelBuilder(wizard);
 
-        final WizardMgtPanel<ProvisionTO> list = builder.build("provision");
+        final WizardMgtPanel<ResourceProvision> list = builder.build("provision");
         add(list);
     }
 
+    private void checkConnObjectKeyCount(final String anyType, final List<ItemTO> items) {
+        long connObjectKeyCount = IterableUtils.countMatches(items, new Predicate<ItemTO>() {
+
+            @Override
+            public boolean evaluate(final ItemTO item) {
+                return item.isConnObjectKey();
+            }
+        });
+
+        if (connObjectKeyCount != 1) {
+            throw new IllegalArgumentException(anyType + ": "
+                    + new StringResourceModel("connObjectKeyValidation", ResourceProvisionPanel.this).getString());
+        }
+    }
+
     @Override
     public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
         try {
-            final Collection<ProvisionTO> provisions = new ArrayList<>(resourceTO.getProvisions());
+            if (resourceTO.getOrgUnit() != null) {
+                checkConnObjectKeyCount(SyncopeConstants.REALM_ANYTYPE, resourceTO.getOrgUnit().getItems());
+            }
 
-            for (ProvisionTO provision : provisions) {
+            for (ProvisionTO provision : new ArrayList<>(resourceTO.getProvisions())) {
                 if (provision != null) {
                     if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) {
                         resourceTO.getProvisions().remove(provision);
                     } else {
-                        long connObjectKeyCount = IterableUtils.countMatches(
-                                provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
-
-                            @Override
-                            public boolean evaluate(final MappingItemTO item) {
-                                return item.isConnObjectKey();
-                            }
-                        });
-
-                        if (connObjectKeyCount != 1) {
-                            throw new IllegalArgumentException(provision.getAnyType() + ": "
-                                    + new StringResourceModel("connObjectKeyValidation", ResourceProvisionPanel.this).
-                                            getString());
-                        }
+                        checkConnObjectKeyCount(provision.getAnyType(), provision.getMapping().getItems());
                     }
                 }
             }
 
-            new ResourceRestClient().update(resourceTO);
+            resourceRestClient.update(resourceTO);
             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
             modal.close(target);
         } catch (Exception e) {
@@ -358,24 +254,13 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
 
-    private void sortProvisionList() {
-        Collections.sort(resourceTO.getProvisions(), new Comparator<ProvisionTO>() {
+    private void sortProvisions() {
+        Collections.sort(provisions, new Comparator<ResourceProvision>() {
 
             @Override
-            public int compare(final ProvisionTO o1, final ProvisionTO o2) {
+            public int compare(final ResourceProvision o1, final ResourceProvision o2) {
                 return new AnyTypeRestClient.AnyTypeKeyComparator().compare(o1.getAnyType(), o2.getAnyType());
             }
         });
     }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent) {
-            aboutRealmProvison.setVisible(false);
-            final AjaxRequestTarget target = ((AjaxWizard.NewItemEvent) event.getPayload()).getTarget();
-            target.add(aboutRealmProvison);
-        }
-
-        super.onEvent(event);
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 5b81fc2..8763e9a 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -575,7 +575,7 @@ div#startAt {
   z-index: 6000 !important;
 }
 
-div#mappingItemTransformersTogglePanel {
+div#itemTransformersTogglePanel {
   min-width: 1000px;
 }
 
@@ -994,12 +994,12 @@ div.transformersContainer #body {
   display: block;
 }
 
-div.mappingItemTransformersContainer #body select {
+div.itemTransformersContainer #body select {
   border: 1px solid #ccc !important;
   background: rgba(240, 240, 240, 0.95) !important
 }
 
-div.mappingItemTransformersContainer #body a {
+div.itemTransformersContainer #body a {
   color: #ccc !important;
   cursor: pointer !important;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
new file mode 100644
index 0000000..5c2d15d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} selected transformer(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
new file mode 100644
index 0000000..8e23aef
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_it.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} transformer selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
new file mode 100644
index 0000000..0fd94d7
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_pt_BR.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+alerts.view.all=View All Mapping Item Tranformers
+summary=${number} JEXL transforming expression(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
new file mode 100644
index 0000000..e79d679
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ItemTransformerWidget_ru.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+alerts.view.all=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
+summary=\u0412\u044b\u0431\u0440\u0430\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432: ${number}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
deleted file mode 100644
index 5c2d15d..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} selected transformer(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
deleted file mode 100644
index 8e23aef..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_it.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} transformer selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
deleted file mode 100644
index 0fd94d7..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_pt_BR.properties
+++ /dev/null
@@ -1,18 +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.
-alerts.view.all=View All Mapping Item Tranformers
-summary=${number} JEXL transforming expression(s)

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
deleted file mode 100644
index e79d679..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/MappingItemTransformerWidget_ru.properties
+++ /dev/null
@@ -1,19 +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.
-#
-alerts.view.all=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
-summary=\u0412\u044b\u0431\u0440\u0430\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432: ${number}

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
index 538d804..57339dd 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/AbstractMappingPanel.html
@@ -57,7 +57,7 @@ under the License.
               </td>
               <td>
                 <div class="alert-widget dropdown tasks-menu">
-                  <span wicket:id="mappingItemTransformers">[Mapping Item Transformers]</span>
+                  <span wicket:id="itemTransformers">[Mapping Item Transformers]</span>
                 </div>
               </td>
               <td>

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
new file mode 100644
index 0000000..01ef653
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.html
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <div id="itemTransformersContainer" class="transformersContainer">
+      <form wicket:id="form">
+        <div id="body">
+          <span wicket:id="classes"/>
+        </div>
+        <div id="footer">
+          <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
+        </div>
+      </form>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
new file mode 100644
index 0000000..06d3702
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Finish
+palette.available=Available Mapping Item Transformers
+palette.selected=Selected Mapping Item Transformers

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
new file mode 100644
index 0000000..9e80b99
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_it.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Fine
+palette.available=Mapping Item Transformer Disponibili
+palette.selected=Mapping Item Transformer Selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
new file mode 100644
index 0000000..d5a72dc
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_pt_BR.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+finish=Finish
+palette.available=Available Mapping Item Transformers
+palette.selected=Mapping Item

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
new file mode 100644
index 0000000..5f823ee
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel_ru.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+finish=\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c
+palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
+palette.selected=\u041c\u0430\u043f\u043f\u0438\u043d\u0433 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
deleted file mode 100644
index 8983a41..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:extend>
-    <div id="mappingItemTransformersContainer" class="transformersContainer">
-      <form wicket:id="form">
-        <div id="body">
-          <span wicket:id="classes"/>
-        </div>
-        <div id="footer">
-          <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
-        </div>
-      </form>
-    </div>
-  </wicket:extend>
-</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
deleted file mode 100644
index 06d3702..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Finish
-palette.available=Available Mapping Item Transformers
-palette.selected=Selected Mapping Item Transformers

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
deleted file mode 100644
index 9e80b99..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_it.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Fine
-palette.available=Mapping Item Transformer Disponibili
-palette.selected=Mapping Item Transformer Selezionati

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
deleted file mode 100644
index d5a72dc..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_pt_BR.properties
+++ /dev/null
@@ -1,19 +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.
-finish=Finish
-palette.available=Available Mapping Item Transformers
-palette.selected=Mapping Item

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
deleted file mode 100644
index 5f823ee..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/MappingItemTransformersTogglePanel_ru.properties
+++ /dev/null
@@ -1,20 +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.
-#
-finish=\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c
-palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432
-palette.selected=\u041c\u0430\u043f\u043f\u0438\u043d\u0433 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
index de5c92f..ef243a8 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.html
@@ -18,14 +18,6 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
-    <div wicket:id="aboutRealmProvison" class="col-xs-12 panel-body">
-      <span wicket:id="enableRealmsProvision"/>
-      <div wicket:id="realmsProvisionContainer">
-        <span wicket:id="objectClass"/>
-        <span wicket:id="extAttrName"/>
-        <span wicket:id="connObjectLink"/>
-      </div>
-    </div>
     <span wicket:id="provision">[PROVISION]</span>
   </wicket:panel>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
index a50917d..47bfff5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.properties
@@ -18,13 +18,8 @@ anyType=Object Type
 objectClass= Object Class
 auxClasses=Auxiliary Classes
 
-extAttrName=External attribute
-
 connObjectKeyValidation=There must be exactly one Remote Key
 propagationMode=Propagation mode
-connObjectLink=Object Link
 enable=Enable
 inner.provision.mapping=${anyType} provision
 inner.provision.clone=Clone provision '${key}'
-enableRealmsProvision=Enable realm provisioning
-enableRealmsProvision.title=Enable the possibility to provision realms towards external resource

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
index 6e7dac6..da47b7f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_it.properties
@@ -18,13 +18,8 @@ anyType=Tipo oggetto
 objectClass=Classe
 auxClasses=Classi Ausiliarie
 
-extAttrName=Attributo esterno
-
 connObjectKeyValidation=Deve essere definito esattamente una Chiave remota
 propagationMode=Modalit\u00e0 di propagazione
-connObjectLink=ID Remoto
 enable=Abilita
 inner.provision.mapping=Provision ${anyType}
 inner.provision.clone=Clona il provision '${key}'
-enableRealmsProvision=Abilita il provisioning dei realm
-enableRealmsProvision.title=Abilita la possibilit\u00e0 di effettuare il provisioning dei realm verso la risorsa esterna

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
index bdd9e92..9f49625 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_pt_BR.properties
@@ -18,13 +18,8 @@ anyType=Object Type
 objectClass=Classe
 auxClasses=Classes Auxiliares
 
-extAttrName=Atributo Externo
-
 connObjectKeyValidation=Precisa ser exatamente um Remote Key
 propagationMode=Modo de propaga\u00e7\u00e3o
-connObjectLink=Remote ID
 enable=Habilitado
 inner.provision.mapping=${anyType} provision
 inner.provision.clone=Clone provision '${key}'
-enableRealmsProvision=Enable realm provisioning
-enableRealmsProvision.title=Enable the possibility to provision realms towards external resource

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
index b06c382..919bd00 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel_ru.properties
@@ -18,13 +18,8 @@ anyType=\u0422\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
 objectClass=\u041a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
 auxClasses=\u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043b\u044e\u0447
 
-extAttrName=\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b
-
 connObjectKeyValidation=\u0422\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
 propagationMode=\u0420\u0435\u0436\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439
-connObjectLink=\u0421\u0432\u044f\u0437\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432
 enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
 inner.provision.mapping=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 ${anyType}
 inner.provision.clone=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 '${key}'
-enableRealmsProvision=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u0438
-enableRealmsProvision.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430

http://git-wip-us.apache.org/repos/asf/syncope/blob/e21971bf/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
index f83b1bd..9dd0b87 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
@@ -87,7 +87,7 @@ public class PlatformInfo extends AbstractBaseBean {
 
     private final Set<String> passwordRules = new HashSet<>();
 
-    private final Set<String> mappingItemTransformers = new HashSet<>();
+    private final Set<String> itemTransformers = new HashSet<>();
 
     private final Set<String> taskJobs = new HashSet<>();
 
@@ -251,11 +251,11 @@ public class PlatformInfo extends AbstractBaseBean {
         return passwordRules;
     }
 
-    @XmlElementWrapper(name = "mappingItemTransformers")
-    @XmlElement(name = "mappingItemTransformer")
-    @JsonProperty("mappingItemTransformers")
-    public Set<String> getMappingItemTransformers() {
-        return mappingItemTransformers;
+    @XmlElementWrapper(name = "itemTransformers")
+    @XmlElement(name = "itemTransformer")
+    @JsonProperty("itemTransformers")
+    public Set<String> getItemTransformers() {
+        return itemTransformers;
     }
 
     @XmlElementWrapper(name = "taskJobs")