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

[45/54] [abbrv] syncope git commit: [SYNCOPE-709] Refactoring completed

[SYNCOPE-709] Refactoring completed


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

Branch: refs/heads/SYNCOPE-156
Commit: 9cd92305562916453bf2aee42bbc3b6d1b07e5cd
Parents: ef28d8e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Oct 22 11:41:00 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Oct 22 11:41:00 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/AnyOperations.java       |  26 +-
 .../syncope/common/lib/patch/AnyPatch.java      |   5 +-
 .../org/apache/syncope/common/lib/to/AnyTO.java |   5 +-
 .../syncope/common/lib/to/ProvisionTO.java      |  18 +
 .../syncope/common/lib/to/VirSchemaTO.java      |  20 ++
 .../common/lib/types/PropagationByResource.java |  11 +
 .../syncope/core/logic/ResourceLogic.java       |  36 +-
 .../core/logic/report/StaticReportlet.java      |   4 +-
 .../core/logic/report/UserReportlet.java        |   8 +-
 .../apache/syncope/core/misc/DataFormat.java    | 117 ------
 .../apache/syncope/core/misc/FormatUtils.java   | 117 ++++++
 .../apache/syncope/core/misc/MappingUtils.java  | 172 +++------
 .../syncope/core/misc/jexl/JexlUtils.java       |  35 +-
 .../core/persistence/api/dao/AnyDAO.java        |   2 +-
 .../core/persistence/api/dao/AnySearchDAO.java  |  10 +-
 .../api/dao/ExternalResourceDAO.java            |   5 +-
 .../core/persistence/api/dao/VirAttrDAO.java    |  35 --
 .../core/persistence/api/dao/VirSchemaDAO.java  |   8 +-
 .../core/persistence/api/entity/Any.java        |  10 +-
 .../core/persistence/api/entity/AnyUtils.java   |   6 +-
 .../persistence/api/entity/AnyUtilsFactory.java |   2 +-
 .../core/persistence/api/entity/Attr.java       |   2 +-
 .../core/persistence/api/entity/DerAttr.java    |   2 +-
 .../api/entity/DynGroupMembership.java          |   2 +-
 .../persistence/api/entity/DynMembership.java   |   2 +-
 .../core/persistence/api/entity/Membership.java |   2 +-
 .../core/persistence/api/entity/PlainAttr.java  |   2 +-
 .../persistence/api/entity/Relationship.java    |   2 +-
 .../core/persistence/api/entity/VirAttr.java    |  30 --
 .../core/persistence/api/entity/VirSchema.java  |  13 +
 .../api/entity/anyobject/AVirAttr.java          |  25 --
 .../api/entity/anyobject/AnyObject.java         |   2 +-
 .../core/persistence/api/entity/conf/Conf.java  |   3 +-
 .../persistence/api/entity/group/GVirAttr.java  |  25 --
 .../persistence/api/entity/group/Group.java     |  14 +-
 .../api/entity/task/PropagationTask.java        |   4 +
 .../persistence/api/entity/user/UVirAttr.java   |  25 --
 .../core/persistence/api/entity/user/User.java  |  14 +-
 .../jpa/content/ContentLoaderHandler.java       |   4 +-
 .../jpa/content/XMLContentExporter.java         |  10 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     |  11 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |  12 +-
 .../core/persistence/jpa/dao/JPADerAttrDAO.java |   2 +-
 .../jpa/dao/JPAExternalResourceDAO.java         |  29 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   2 +-
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    |   2 +-
 .../jpa/dao/JPAPlainAttrValueDAO.java           |   7 +-
 .../core/persistence/jpa/dao/JPAVirAttrDAO.java |  86 -----
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |  35 +-
 .../persistence/jpa/entity/AbstractAny.java     |  17 +-
 .../persistence/jpa/entity/AbstractAttr.java    |   2 +-
 .../persistence/jpa/entity/AbstractDerAttr.java |   2 +-
 .../jpa/entity/AbstractDynMembership.java       |   2 +-
 .../jpa/entity/AbstractPlainAttr.java           |   2 +-
 .../jpa/entity/AbstractPlainAttrValue.java      |  18 +-
 .../persistence/jpa/entity/AbstractVirAttr.java |  71 ----
 .../jpa/entity/AnnotatedEntityListener.java     |   4 +-
 .../persistence/jpa/entity/JPAAnyUtils.java     |  52 +--
 .../jpa/entity/JPAAnyUtilsFactory.java          |   2 +-
 .../jpa/entity/JPAEntityFactory.java            |   8 -
 .../persistence/jpa/entity/JPAVirSchema.java    | 147 ++++++++
 .../anyobject/JPAAPlainAttrUniqueValue.java     |   2 +-
 .../entity/anyobject/JPAAPlainAttrValue.java    |   2 +-
 .../jpa/entity/anyobject/JPAAVirAttr.java       |  59 ---
 .../jpa/entity/anyobject/JPAAnyObject.java      |  24 +-
 .../entity/conf/JPACPlainAttrUniqueValue.java   |   2 +-
 .../jpa/entity/conf/JPACPlainAttrValue.java     |   2 +-
 .../persistence/jpa/entity/conf/JPAConf.java    |  21 --
 .../entity/group/JPAGPlainAttrUniqueValue.java  |   2 +-
 .../jpa/entity/group/JPAGPlainAttrValue.java    |   2 +-
 .../jpa/entity/group/JPAGVirAttr.java           |  59 ---
 .../persistence/jpa/entity/group/JPAGroup.java  |  24 +-
 .../jpa/entity/resource/JPAMapping.java         |  27 +-
 .../jpa/entity/resource/JPAProvision.java       |   1 -
 .../jpa/entity/task/JPAPropagationTask.java     |  12 +
 .../entity/user/JPAUPlainAttrUniqueValue.java   |   2 +-
 .../jpa/entity/user/JPAUPlainAttrValue.java     |   2 +-
 .../jpa/entity/user/JPAUVirAttr.java            |  59 ---
 .../persistence/jpa/entity/user/JPAUser.java    |  24 +-
 .../entity/ExternalResourceValidator.java       |  45 ++-
 .../jpa/validation/entity/PlainAttrCheck.java   |   2 +-
 .../validation/entity/PlainAttrValidator.java   |   2 +-
 .../resources/META-INF/spring-orm-oracle.xml    |  25 --
 .../resources/META-INF/spring-orm-sqlserver.xml |  25 --
 .../src/main/resources/META-INF/spring-orm.xml  |  25 --
 .../src/main/resources/indexes.xml              |   4 -
 .../persistence/jpa/inner/PlainAttrTest.java    |   1 -
 .../persistence/jpa/inner/ResourceTest.java     |  46 +++
 .../core/persistence/jpa/inner/TaskTest.java    |   1 +
 .../core/persistence/jpa/inner/VirAttrTest.java | 118 ------
 .../persistence/jpa/inner/VirSchemaTest.java    |  12 +-
 .../persistence/jpa/outer/ResourceTest.java     |  15 +-
 .../core/persistence/jpa/outer/TaskTest.java    |   1 +
 .../persistence/jpa/outer/VirSchemaTest.java    |  76 ++++
 .../test/resources/domains/MasterContent.xml    |  29 +-
 .../core/provisioning/api/Connector.java        |  27 +-
 .../core/provisioning/api/VirAttrHandler.java   |  52 +--
 .../api/cache/VirAttrCacheValue.java            |  36 +-
 .../api/propagation/PropagationManager.java     |   5 +-
 .../core/provisioning/api/sync/PushActions.java |  20 +-
 .../provisioning/java/ConnectorFacadeProxy.java |  29 +-
 .../DefaultAnyObjectProvisioningManager.java    |  12 -
 .../java/DefaultGroupProvisioningManager.java   |  12 -
 .../java/DefaultUserProvisioningManager.java    |  30 +-
 .../provisioning/java/VirAttrHandlerImpl.java   | 356 ++++---------------
 .../java/data/AbstractAnyDataBinder.java        | 138 +++----
 .../java/data/AnyObjectDataBinderImpl.java      |  11 +-
 .../java/data/GroupDataBinderImpl.java          |  11 +-
 .../java/data/ResourceDataBinderImpl.java       |  48 ++-
 .../java/data/SchemaDataBinderImpl.java         |  16 +-
 .../java/data/UserDataBinderImpl.java           |  11 +-
 .../core/provisioning/java/job/TaskJob.java     |   4 +-
 .../notification/NotificationManagerImpl.java   |  26 +-
 .../AbstractPropagationTaskExecutor.java        |  89 +++--
 .../propagation/PropagationManagerImpl.java     | 248 +++++++------
 .../java/sync/AbstractPushResultHandler.java    |  57 +--
 .../java/sync/AbstractSyncResultHandler.java    |  42 ++-
 .../java/sync/AbstractSyncopeResultHandler.java |   2 +-
 .../sync/AnyObjectPushResultHandlerImpl.java    |   4 +-
 .../sync/AnyObjectSyncResultHandlerImpl.java    |   2 +-
 .../java/sync/DefaultPushActions.java           |  16 +-
 .../java/sync/GroupPushResultHandlerImpl.java   |   4 +-
 .../java/sync/GroupSyncResultHandlerImpl.java   |   2 +-
 .../provisioning/java/sync/PushJobDelegate.java |   4 +-
 .../provisioning/java/sync/SyncJobDelegate.java |  31 +-
 .../core/provisioning/java/sync/SyncUtils.java  |  12 +-
 .../java/sync/UserPushResultHandlerImpl.java    |   6 +-
 .../java/sync/UserSyncResultHandlerImpl.java    |   2 +-
 .../rest/cxf/ThreadLocalCleanupListener.java    |   4 +-
 .../rest/cxf/service/AbstractAnyService.java    |   9 +-
 .../processor/AnyObjectUpdateProcessor.java     |  13 -
 .../camel/processor/GroupUpdateProcessor.java   |  13 -
 .../processor/UserUpdateInSyncProcessor.java    |   6 +-
 .../camel/processor/UserUpdateProcessor.java    |  27 +-
 fit/console-reference/pom.xml                   |  81 +----
 fit/core-reference/pom.xml                      |  16 +-
 .../syncope/fit/core/reference/GroupITCase.java |  26 +-
 .../core/reference/PropagationTaskITCase.java   |   8 -
 .../fit/core/reference/SyncTaskITCase.java      |  20 +-
 .../syncope/fit/core/reference/UserITCase.java  |  53 +--
 .../fit/core/reference/VirAttrITCase.java       | 329 +++++++++--------
 .../fit/core/reference/VirSchemaITCase.java     |  41 ++-
 142 files changed, 1609 insertions(+), 2503 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
index e1f9f88..0e5bec3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
@@ -150,29 +150,8 @@ public final class AnyOperations {
         }
 
         // 5. virtual attributes
-        updatedAttrs = updated.getVirAttrMap();
-        originalAttrs = original.getVirAttrMap();
-
         result.getVirAttrs().clear();
-
-        if (!incremental) {
-            CollectionUtils.forAllDo(CollectionUtils.subtract(originalAttrs.keySet(), updatedAttrs.keySet()),
-                    new Closure<String>() {
-
-                        @Override
-                        public void execute(final String schema) {
-                            result.getVirAttrs().add(new AttrPatch.Builder().
-                                    operation(PatchOperation.DELETE).
-                                    attrTO(new AttrTO.Builder().schema(schema).build()).
-                                    build());
-                        }
-                    });
-        }
-
-        for (AttrTO attrTO : updatedAttrs.values()) {
-            AttrPatch patch = new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).attrTO(attrTO).build();
-            result.getVirAttrs().add(patch);
-        }
+        result.getVirAttrs().addAll(updated.getVirAttrs());
 
         // 6. resources
         result.getResources().clear();
@@ -188,7 +167,6 @@ public final class AnyOperations {
             result.getResources().add(
                     new StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value(resource).build());
         }
-
     }
 
     /**
@@ -450,7 +428,7 @@ public final class AnyOperations {
 
         // 4. virtual attributes
         result.getVirAttrs().clear();
-        result.getVirAttrs().addAll(AnyOperations.patch(to.getVirAttrMap(), patch.getVirAttrs()));
+        result.getVirAttrs().addAll(patch.getVirAttrs());
 
         // 5. resources
         for (StringPatchItem resourcePatch : patch.getResources()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
index e4b9e87..a6c4323 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
@@ -27,6 +27,7 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.to.AttrTO;
 
 @XmlType
 public abstract class AnyPatch extends AbstractBaseBean {
@@ -43,7 +44,7 @@ public abstract class AnyPatch extends AbstractBaseBean {
 
     private final Set<AttrPatch> derAttrs = new HashSet<>();
 
-    private final Set<AttrPatch> virAttrs = new HashSet<>();
+    private final Set<AttrTO> virAttrs = new HashSet<>();
 
     private final Set<StringPatchItem> resources = new HashSet<>();
 
@@ -88,7 +89,7 @@ public abstract class AnyPatch extends AbstractBaseBean {
     @XmlElementWrapper(name = "virAttrs")
     @XmlElement(name = "attribute")
     @JsonProperty("virAttrs")
-    public Set<AttrPatch> getVirAttrs() {
+    public Set<AttrTO> getVirAttrs() {
         return virAttrs;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index 56b1c44..7911d7d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -25,7 +25,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -53,9 +52,9 @@ public abstract class AnyTO extends ConnObjectTO {
 
     private final List<String> auxClasses = new ArrayList<>();
 
-    private final Set<AttrTO> derAttrs = new LinkedHashSet<>();
+    private final Set<AttrTO> derAttrs = new HashSet<>();
 
-    private final Set<AttrTO> virAttrs = new LinkedHashSet<>();
+    private final Set<AttrTO> virAttrs = new HashSet<>();
 
     private final Set<String> resources = new HashSet<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
index c4ff740..b25053d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
@@ -18,8 +18,17 @@
  */
 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;
 
+@XmlRootElement(name = "provision")
+@XmlType
 public class ProvisionTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 8298910216218007927L;
@@ -34,6 +43,8 @@ public class ProvisionTO extends AbstractBaseBean {
 
     private MappingTO mapping;
 
+    private List<String> virSchemas = new ArrayList<>();
+
     public long getKey() {
         return key;
     }
@@ -74,4 +85,11 @@ public class ProvisionTO extends AbstractBaseBean {
         this.mapping = mapping;
     }
 
+    @XmlElementWrapper(name = "virSchemas")
+    @XmlElement(name = "virSchema")
+    @JsonProperty("virSchemas")
+    public List<String> getVirSchemas() {
+        return virSchemas;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
index 1a9d3bd..8c3df1b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
@@ -27,6 +27,10 @@ public class VirSchemaTO extends AbstractSchemaTO {
 
     private boolean readonly;
 
+    private long provision;
+
+    private String extAttrName;
+
     public boolean isReadonly() {
         return readonly;
     }
@@ -35,4 +39,20 @@ public class VirSchemaTO extends AbstractSchemaTO {
         this.readonly = readonly;
     }
 
+    public long getProvision() {
+        return provision;
+    }
+
+    public void setProvision(final long provision) {
+        this.provision = provision;
+    }
+
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
index bf35bb3..3e35fec 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
@@ -263,6 +263,17 @@ public class PropagationByResource implements Serializable {
         return result;
     }
 
+    public Map<String, ResourceOperation> asMap() {
+        Map<String, ResourceOperation> result = new HashMap<>();
+        for (ResourceOperation operation : ResourceOperation.values()) {
+            for (String resourceName : get(operation)) {
+                result.put(resourceName, operation);
+            }
+        }
+
+        return result;
+    }
+
     /**
      * Set resources for a given resource operation type.
      *

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/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 c3ce0c6..44a5aa8 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
@@ -20,9 +20,12 @@ package org.apache.syncope.core.logic;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.ArrayUtils;
@@ -51,9 +54,11 @@ import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.MappingUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -86,6 +91,9 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private GroupDAO groupDAO;
 
     @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
     private ResourceDataBinder binder;
 
     @Autowired
@@ -205,7 +213,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     public ConnObjectTO readConnObject(final String key, final String anyTypeKey, final Long anyKey) {
         Triple<ExternalResource, AnyType, Provision> init = connObjectInit(key, anyTypeKey);
 
-        Any<?, ?, ?> any = init.getMiddle().getKind() == AnyTypeKind.USER
+        // 1. find any
+        Any<?, ?> any = init.getMiddle().getKind() == AnyTypeKind.USER
                 ? userDAO.find(anyKey)
                 : init.getMiddle().getKind() == AnyTypeKind.ANY_OBJECT
                         ? anyObjectDAO.find(anyKey)
@@ -213,6 +222,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (any == null) {
             throw new NotFoundException(init.getMiddle() + " " + anyKey);
         }
+
+        // 2. build connObjectKeyItem
         MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(init.getRight());
         if (connObjectKeyItem == null) {
             throw new NotFoundException(
@@ -220,17 +231,28 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         }
         String connObjectKeyValue = mappingUtils.getConnObjectKeyValue(any, init.getRight());
 
+        // 3. determine attributes to query
+        Set<MappingItem> linkinMappingItems = new HashSet<>();
+        for (VirSchema virSchema : virSchemaDAO.findByProvision(init.getRight())) {
+            linkinMappingItems.add(virSchema.asLinkingMappingItem());
+        }
+        Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
+                init.getRight().getMapping().getItems().iterator(),
+                linkinMappingItems.iterator());
+
+        // 4. read from the underlying connector
         Connector connector = connFactory.getConnector(init.getLeft());
         ConnectorObject connectorObject = connector.getObject(
                 init.getRight().getObjectClass(),
                 new Uid(connObjectKeyValue),
-                connector.getOperationOptions(MappingUtils.getBothMappingItems(init.getRight())));
+                connector.getOperationOptions(mapItems));
         if (connectorObject == null) {
             throw new NotFoundException(
                     "Object " + connObjectKeyValue + " with class " + init.getRight().getObjectClass()
                     + " not found on resource " + key);
         }
 
+        // 5. build result
         Set<Attribute> attributes = connectorObject.getAttributes();
         if (AttributeUtil.find(Uid.NAME, attributes) == null) {
             attributes.add(connectorObject.getUid());
@@ -251,6 +273,14 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
         Connector connector = connFactory.getConnector(init.getLeft());
 
+        Set<MappingItem> linkinMappingItems = new HashSet<>();
+        for (VirSchema virSchema : virSchemaDAO.findByProvision(init.getRight())) {
+            linkinMappingItems.add(virSchema.asLinkingMappingItem());
+        }
+        Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
+                init.getRight().getMapping().getItems().iterator(),
+                linkinMappingItems.iterator());
+
         final SearchResult[] searchResult = new SearchResult[1];
         final List<ConnObjectTO> connObjects = new ArrayList<>();
         connector.search(init.getRight().getObjectClass(), null, new SearchResultsHandler() {
@@ -265,7 +295,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 connObjects.add(connObjectUtils.getConnObjectTO(connectorObject));
                 return true;
             }
-        }, size, pagedResultsCookie, orderBy);
+        }, size, pagedResultsCookie, orderBy, mapItems);
 
         return ImmutablePair.of(searchResult[0], connObjects);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
index b7db39f..0e785b1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic.report;
 import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.report.StaticReportletConf;
-import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.FormatUtils;
 import org.springframework.util.StringUtils;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -101,7 +101,7 @@ public class StaticReportlet extends AbstractReportlet {
 
         if (this.conf.getDateField() != null) {
             handler.startElement("", "", "date", null);
-            String printed = DataFormat.format(this.conf.getDateField());
+            String printed = FormatUtils.format(this.conf.getDateField());
             handler.characters(printed.toCharArray(), 0, printed.length());
             handler.endElement("", "", "date");
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index c11ca05..3eb96b3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -38,7 +38,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.FormatUtils;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.URelationship;
@@ -231,21 +231,21 @@ public class UserReportlet extends AbstractReportlet {
                         type = ReportXMLConst.XSD_DATETIME;
                         value = user.getCreationDate() == null
                                 ? ""
-                                : DataFormat.format(user.getCreationDate());
+                                : FormatUtils.format(user.getCreationDate());
                         break;
 
                     case lastLoginDate:
                         type = ReportXMLConst.XSD_DATETIME;
                         value = user.getLastLoginDate() == null
                                 ? ""
-                                : DataFormat.format(user.getLastLoginDate());
+                                : FormatUtils.format(user.getLastLoginDate());
                         break;
 
                     case changePwdDate:
                         type = ReportXMLConst.XSD_DATETIME;
                         value = user.getChangePwdDate() == null
                                 ? ""
-                                : DataFormat.format(user.getChangePwdDate());
+                                : FormatUtils.format(user.getChangePwdDate());
                         break;
 
                     case passwordHistorySize:

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/misc/src/main/java/org/apache/syncope/core/misc/DataFormat.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/DataFormat.java b/core/misc/src/main/java/org/apache/syncope/core/misc/DataFormat.java
deleted file mode 100644
index fded378..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/DataFormat.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.misc;
-
-import java.text.DecimalFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import org.apache.commons.lang3.time.DateUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-
-/**
- * Utility class for parsing / formatting date and numbers.
- */
-public final class DataFormat {
-
-    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-
-        @Override
-        protected SimpleDateFormat initialValue() {
-            SimpleDateFormat sdf = new SimpleDateFormat();
-            sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
-            return sdf;
-        }
-    };
-
-    private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
-
-        @Override
-        protected DecimalFormat initialValue() {
-            return new DecimalFormat();
-        }
-    };
-
-    public static String format(final Date date) {
-        return format(date, true);
-    }
-
-    public static String format(final Date date, final boolean lenient) {
-        return format(date, lenient, null);
-    }
-
-    public static String format(final Date date, final boolean lenient, final String conversionPattern) {
-        SimpleDateFormat sdf = DATE_FORMAT.get();
-        if (conversionPattern != null) {
-            sdf.applyPattern(conversionPattern);
-        }
-        sdf.setLenient(lenient);
-        return sdf.format(date);
-    }
-
-    public static String format(final long number) {
-        return format(number, null);
-    }
-
-    public static String format(final long number, final String conversionPattern) {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        if (conversionPattern != null) {
-            df.applyPattern(conversionPattern);
-        }
-        return df.format(number);
-    }
-
-    public static String format(final double number) {
-        return format(number, null);
-    }
-
-    public static String format(final double number, final String conversionPattern) {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        if (conversionPattern != null) {
-            df.applyPattern(conversionPattern);
-        }
-        return df.format(number);
-    }
-
-    public static Date parseDate(final String source) throws ParseException {
-        return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
-    }
-
-    public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
-        SimpleDateFormat sdf = DATE_FORMAT.get();
-        sdf.applyPattern(conversionPattern);
-        sdf.setLenient(false);
-        return sdf.parse(source);
-    }
-
-    public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
-        DecimalFormat df = DECIMAL_FORMAT.get();
-        df.applyPattern(conversionPattern);
-        return df.parse(source);
-    }
-
-    public static void clear() {
-        DATE_FORMAT.remove();
-        DECIMAL_FORMAT.remove();
-    }
-
-    private DataFormat() {
-        // private empty constructor
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
new file mode 100644
index 0000000..0b06906
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/FormatUtils.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc;
+
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+
+/**
+ * Utility class for parsing / formatting date and numbers.
+ */
+public final class FormatUtils {
+
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+        @Override
+        protected SimpleDateFormat initialValue() {
+            SimpleDateFormat sdf = new SimpleDateFormat();
+            sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+            return sdf;
+        }
+    };
+
+    private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
+
+        @Override
+        protected DecimalFormat initialValue() {
+            return new DecimalFormat();
+        }
+    };
+
+    public static String format(final Date date) {
+        return format(date, true);
+    }
+
+    public static String format(final Date date, final boolean lenient) {
+        return format(date, lenient, null);
+    }
+
+    public static String format(final Date date, final boolean lenient, final String conversionPattern) {
+        SimpleDateFormat sdf = DATE_FORMAT.get();
+        if (conversionPattern != null) {
+            sdf.applyPattern(conversionPattern);
+        }
+        sdf.setLenient(lenient);
+        return sdf.format(date);
+    }
+
+    public static String format(final long number) {
+        return format(number, null);
+    }
+
+    public static String format(final long number, final String conversionPattern) {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        if (conversionPattern != null) {
+            df.applyPattern(conversionPattern);
+        }
+        return df.format(number);
+    }
+
+    public static String format(final double number) {
+        return format(number, null);
+    }
+
+    public static String format(final double number, final String conversionPattern) {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        if (conversionPattern != null) {
+            df.applyPattern(conversionPattern);
+        }
+        return df.format(number);
+    }
+
+    public static Date parseDate(final String source) throws ParseException {
+        return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
+    }
+
+    public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
+        SimpleDateFormat sdf = DATE_FORMAT.get();
+        sdf.applyPattern(conversionPattern);
+        sdf.setLenient(false);
+        return sdf.parse(source);
+    }
+
+    public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
+        DecimalFormat df = DECIMAL_FORMAT.get();
+        df.applyPattern(conversionPattern);
+        return df.parse(source);
+    }
+
+    public static void clear() {
+        DATE_FORMAT.remove();
+        DECIMAL_FORMAT.remove();
+    }
+
+    private FormatUtils() {
+        // private empty constructor
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index 085f07d..54a4428 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -19,15 +19,11 @@
 package org.apache.syncope.core.misc;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.jexl2.JexlContext;
 import org.apache.commons.jexl2.MapContext;
 import org.apache.commons.lang3.ClassUtils;
@@ -35,7 +31,6 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AttrPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -53,7 +48,6 @@ 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.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
@@ -70,6 +64,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Schema;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -122,42 +117,6 @@ public class MappingUtils {
     @Autowired
     private AnyUtilsFactory anyUtilsFactory;
 
-    public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
-            final Collection<T> items, final IntMappingType type) {
-
-        return CollectionUtils.select(items, new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T item) {
-                return item.getIntMappingType() == type;
-            }
-        });
-    }
-
-    public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
-            final Collection<T> items, final String intAttrName, final IntMappingType type) {
-
-        return CollectionUtils.select(items, new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T item) {
-                return item.getIntMappingType() == type && intAttrName.equals(item.getIntAttrName());
-            }
-        });
-    }
-
-    public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
-            final Collection<T> items, final String intAttrName) {
-
-        return CollectionUtils.select(items, new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T item) {
-                return intAttrName.equals(item.getIntAttrName());
-            }
-        });
-    }
-
     public static MappingItem getConnObjectKeyItem(final Provision provision) {
         Mapping mapping = null;
         if (provision != null) {
@@ -241,7 +200,7 @@ public class MappingUtils {
      * @param connObjectKey connector object key
      * @return the value to be propagated as __NAME__
      */
-    public static Name evaluateNAME(final Any<?, ?, ?> any, final Provision provision, final String connObjectKey) {
+    public static Name evaluateNAME(final Any<?, ?> any, final Provision provision, final String connObjectKey) {
         if (StringUtils.isBlank(connObjectKey)) {
             // LOG error but avoid to throw exception: leave it to the external resource
             LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
@@ -302,17 +261,15 @@ public class MappingUtils {
      * @param any given any object
      * @param password clear-text password
      * @param changePwd whether password should be included for propagation attributes or not
-     * @param vAttrs virtual attributes to be managed
      * @param enable whether any object must be enabled or not
      * @param provision provision information
      * @return connObjectLink + prepared attributes
      */
     @Transactional(readOnly = true)
     public Pair<String, Set<Attribute>> prepareAttrs(
-            final Any<?, ?, ?> any,
+            final Any<?, ?> any,
             final String password,
             final boolean changePwd,
-            final Map<String, AttrPatch> vAttrs,
             final Boolean enable,
             final Provision provision) {
 
@@ -322,19 +279,11 @@ public class MappingUtils {
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
 
-        for (MappingItem mapping : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
-            LOG.debug("Processing schema {}", mapping.getIntAttrName());
+        for (MappingItem mappingItem : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+            LOG.debug("Processing schema {}", mappingItem.getIntAttrName());
 
             try {
-                if (mapping.getIntMappingType() == IntMappingType.UserVirtualSchema
-                        || mapping.getIntMappingType() == IntMappingType.GroupVirtualSchema
-                        || mapping.getIntMappingType() == IntMappingType.AnyObjectVirtualSchema) {
-
-                    LOG.debug("Expire entry cache {}-{}", any.getKey(), mapping.getIntAttrName());
-                    virAttrCache.expire(any.getType().getKey(), any.getKey(), mapping.getIntAttrName());
-                }
-
-                Pair<String, Attribute> preparedAttr = prepareAttr(provision, mapping, any, password, vAttrs);
+                Pair<String, Attribute> preparedAttr = prepareAttr(provision, mappingItem, any, password);
 
                 if (preparedAttr != null && preparedAttr.getKey() != null) {
                     connObjectKey = preparedAttr.getKey();
@@ -355,7 +304,7 @@ public class MappingUtils {
                     }
                 }
             } catch (Exception e) {
-                LOG.debug("Attribute '{}' processing failed", mapping.getIntAttrName(), e);
+                LOG.debug("Attribute '{}' processing failed", mappingItem.getIntAttrName(), e);
             }
         }
 
@@ -387,15 +336,12 @@ public class MappingUtils {
      * @param mapItem mapping item for the given attribute
      * @param any any object
      * @param password clear-text password
-     * @param vAttrs virtual attributes to be managed
      * @return connObjectLink + prepared attribute
      */
     private Pair<String, Attribute> prepareAttr(
-            final Provision provision, final MappingItem mapItem,
-            final Any<?, ?, ?> any, final String password,
-            final Map<String, AttrPatch> vAttrs) {
+            final Provision provision, final MappingItem mapItem, final Any<?, ?> any, final String password) {
 
-        List<Any<?, ?, ?>> anys = new ArrayList<>();
+        List<Any<?, ?>> anys = new ArrayList<>();
 
         switch (mapItem.getIntMappingType().getAnyTypeKind()) {
             case USER:
@@ -407,7 +353,6 @@ public class MappingUtils {
             case GROUP:
                 if (any instanceof User) {
                     for (Group group : userDAO.findAllGroups((User) any)) {
-                        virAttrHandler.retrieveVirAttrValues(group);
                         anys.add(group);
                     }
                 } else if (any instanceof Group) {
@@ -424,8 +369,6 @@ public class MappingUtils {
             default:
         }
 
-        List<PlainAttrValue> values = getIntValues(provision, mapItem, anys, vAttrs);
-
         Schema schema = null;
         boolean readOnlyVirSchema = false;
         AttrSchemaType schemaType;
@@ -453,6 +396,8 @@ public class MappingUtils {
 
         String extAttrName = mapItem.getExtAttrName();
 
+        List<PlainAttrValue> values = getIntValues(provision, mapItem, anys);
+
         LOG.debug("Define mapping for: "
                 + "\n* ExtAttrName " + extAttrName
                 + "\n* is connObjectKey " + mapItem.isConnObjectKey()
@@ -501,8 +446,7 @@ public class MappingUtils {
                     result = null;
                 } else {
                     result = new ImmutablePair<>(
-                            null,
-                            AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
+                            null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
                 }
             } else {
                 if ((schema != null && schema.isMultivalue())
@@ -510,8 +454,7 @@ public class MappingUtils {
                         != mapItem.getIntMappingType().getAnyTypeKind()) {
 
                     result = new ImmutablePair<>(
-                            null,
-                            AttributeBuilder.build(extAttrName, objValues));
+                            null, AttributeBuilder.build(extAttrName, objValues));
                 } else {
                     result = new ImmutablePair<>(
                             null, objValues.isEmpty()
@@ -524,9 +467,8 @@ public class MappingUtils {
         return result;
     }
 
-    private String getGroupOwnerValue(final Provision provision, final Any<?, ?, ?> any) {
-        Pair<String, Attribute> preparedAttr = prepareAttr(
-                provision, getConnObjectKeyItem(provision), any, null, Collections.<String, AttrPatch>emptyMap());
+    private String getGroupOwnerValue(final Provision provision, final Any<?, ?> any) {
+        Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision), any, null);
         String connObjectKey = preparedAttr.getKey();
 
         return evaluateNAME(any, provision, connObjectKey).getNameValue();
@@ -538,12 +480,11 @@ public class MappingUtils {
      * @param provision provision information
      * @param mappingItem mapping item
      * @param anys any objects
-     * @param vAttrs virtual attributes to be managed
      * @return attribute values.
      */
     @Transactional(readOnly = true)
     public List<PlainAttrValue> getIntValues(final Provision provision,
-            final MappingItem mappingItem, final List<Any<?, ?, ?>> anys, final Map<String, AttrPatch> vAttrs) {
+            final MappingItem mappingItem, final List<Any<?, ?>> anys) {
 
         LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
 
@@ -554,7 +495,7 @@ public class MappingUtils {
             case UserPlainSchema:
             case GroupPlainSchema:
             case AnyObjectPlainSchema:
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
                         if (attr.getUniqueValue() != null) {
@@ -579,46 +520,10 @@ public class MappingUtils {
 
                 break;
 
-            case UserVirtualSchema:
-            case GroupVirtualSchema:
-            case AnyObjectVirtualSchema:
-                // virtual attributes don't get transformed
-                transform = false;
-
-                for (Any<?, ?, ?> any : anys) {
-                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-                    VirAttr<?> attr = any.getVirAttr(mappingItem.getIntAttrName());
-                    if (attr != null) {
-                        if (vAttrs != null) {
-                            if (vAttrs.containsKey(mappingItem.getIntAttrName())) {
-                                attr.getValues().clear();
-                                attr.getValues().addAll(
-                                        vAttrs.get(mappingItem.getIntAttrName()).getAttrTO().getValues());
-                            } else {
-                                throw new IllegalArgumentException("Don't need to update virtual attribute '"
-                                        + mappingItem.getIntAttrName() + "'");
-                            }
-                        }
-                        for (String value : attr.getValues()) {
-                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
-                            attrValue.setStringValue(value);
-                            values.add(attrValue);
-                        }
-                    }
-
-                    LOG.debug("Retrieved {} virtual attribute {}"
-                            + "\n* IntAttrName {}"
-                            + "\n* IntMappingType {}"
-                            + "\n* Attribute values {}",
-                            any.getClass().getSimpleName(),
-                            attr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
-                }
-                break;
-
             case UserDerivedSchema:
             case GroupDerivedSchema:
             case AnyObjectDerivedSchema:
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     DerAttr<?> attr = any.getDerAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
@@ -635,10 +540,39 @@ public class MappingUtils {
                 }
                 break;
 
+            case UserVirtualSchema:
+            case GroupVirtualSchema:
+            case AnyObjectVirtualSchema:
+                // virtual attributes don't get transformed
+                transform = false;
+
+                VirSchema virSchema = virSchemaDAO.find(mappingItem.getIntAttrName());
+                if (virSchema != null) {
+                    for (Any<?, ?> any : anys) {
+                        LOG.debug("Expire entry cache {}-{}", any.getKey(), mappingItem.getIntAttrName());
+                        virAttrCache.expire(any.getType().getKey(), any.getKey(), mappingItem.getIntAttrName());
+
+                        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                        for (String value : virAttrHandler.getValues(any, virSchema)) {
+                            PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+                            attrValue.setStringValue(value);
+                            values.add(attrValue);
+                        }
+
+                        LOG.debug("Retrieved values for {}"
+                                + "\n* IntAttrName {}"
+                                + "\n* IntMappingType {}"
+                                + "\n* Attribute values {}",
+                                virSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
+                                values);
+                    }
+                }
+                break;
+
             case UserKey:
             case GroupKey:
             case AnyObjectKey:
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
                     attrValue.setStringValue(any.getKey().toString());
@@ -647,7 +581,7 @@ public class MappingUtils {
                 break;
 
             case Username:
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     if (any instanceof User) {
                         UPlainAttrValue attrValue = entityFactory.newEntity(UPlainAttrValue.class);
                         attrValue.setStringValue(((User) any).getUsername());
@@ -657,7 +591,7 @@ public class MappingUtils {
                 break;
 
             case GroupName:
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     if (any instanceof Group) {
                         GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
                         attrValue.setStringValue(((Group) any).getName());
@@ -674,7 +608,7 @@ public class MappingUtils {
                         ? null
                         : provision.getMapping();
 
-                for (Any<?, ?, ?> any : anys) {
+                for (Any<?, ?> any : anys) {
                     if (any instanceof Group) {
                         Group group = (Group) any;
                         String groupOwnerValue = null;
@@ -720,9 +654,9 @@ public class MappingUtils {
      * @return connObjectKey internal value
      */
     @Transactional(readOnly = true)
-    public String getConnObjectKeyValue(final Any<?, ?, ?> any, final Provision provision) {
+    public String getConnObjectKeyValue(final Any<?, ?> any, final Provision provision) {
         List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
-                Collections.<Any<?, ?, ?>>singletonList(any), null);
+                Collections.<Any<?, ?>>singletonList(any));
         return values == null || values.isEmpty()
                 ? null
                 : values.get(0).getValueAsString();

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
index 443bbae..3afe6e5 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
@@ -35,8 +35,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.FormatUtils;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.slf4j.Logger;
@@ -126,7 +125,7 @@ public final class JexlUtils {
                         context.set(fieldName, fieldValue == null
                                 ? StringUtils.EMPTY
                                 : (type.equals(Date.class)
-                                        ? DataFormat.format((Date) fieldValue, false)
+                                        ? FormatUtils.format((Date) fieldValue, false)
                                         : fieldValue));
 
                         LOG.debug("Add field {} with value {}", fieldName, fieldValue);
@@ -140,7 +139,7 @@ public final class JexlUtils {
         }
 
         if (object instanceof Any) {
-            Any<?, ?, ?> any = (Any<?, ?, ?>) object;
+            Any<?, ?> any = (Any<?, ?>) object;
             if (any.getRealm() != null) {
                 context.set("realm", any.getRealm().getName());
             }
@@ -195,40 +194,16 @@ public final class JexlUtils {
         return context;
     }
 
-    public static JexlContext addVirAttrsToContext(final Collection<? extends VirAttr> virAttrs,
-            final JexlContext jexlContext) {
-
-        JexlContext context = jexlContext == null
-                ? new MapContext()
-                : jexlContext;
-
-        for (VirAttr<?> virAttr : virAttrs) {
-            if (virAttr.getSchema() != null) {
-                List<String> attrValues = virAttr.getValues();
-                String expressionValue = attrValues.isEmpty()
-                        ? StringUtils.EMPTY
-                        : attrValues.get(0);
-
-                LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema().getKey(), expressionValue);
-
-                context.set(virAttr.getSchema().getKey(), expressionValue);
-            }
-        }
-
-        return context;
-    }
-
-    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?, ?, ?> any) {
+    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?, ?> any) {
         JexlContext jexlContext = new MapContext();
         addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
         addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
-        addVirAttrsToContext(any.getVirAttrs(), jexlContext);
 
         return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
     }
 
     public static String evaluate(final String expression,
-            final Any<?, ?, ?> any, final Collection<? extends PlainAttr<?>> attributes) {
+            final Any<?, ?> any, final Collection<? extends PlainAttr<?>> attributes) {
 
         JexlContext jexlContext = new MapContext();
         JexlUtils.addPlainAttrsToContext(attributes, jexlContext);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
index 86c97e3..bfda35f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
@@ -25,7 +25,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 
-public interface AnyDAO<A extends Any<?, ?, ?>> extends DAO<A, Long> {
+public interface AnyDAO<A extends Any<?, ?>> extends DAO<A, Long> {
 
     A authFind(Long key);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
index f53dff6..00471e0 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
@@ -25,7 +25,7 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 
-public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
+public interface AnySearchDAO extends DAO<Any<?, ?>, Long> {
 
     /**
      * @param adminRealms realms for which the caller owns the proper entitlement(s)
@@ -42,7 +42,7 @@ public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
      * @param <T> any
      * @return the list of any objects matching the given search condition
      */
-    <T extends Any<?, ?, ?>> List<T> search(
+    <T extends Any<?, ?>> List<T> search(
             Set<String> adminRealms, SearchCond searchCondition, AnyTypeKind kind);
 
     /**
@@ -53,7 +53,7 @@ public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
      * @param <T> any
      * @return the list of any objects matching the given search condition
      */
-    <T extends Any<?, ?, ?>> List<T> search(
+    <T extends Any<?, ?>> List<T> search(
             Set<String> adminRealms, SearchCond searchCondition, List<OrderByClause> orderBy, AnyTypeKind kind);
 
     /**
@@ -66,7 +66,7 @@ public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
      * @param <T> any
      * @return the list of any objects matching the given search condition (in the given page)
      */
-    <T extends Any<?, ?, ?>> List<T> search(
+    <T extends Any<?, ?>> List<T> search(
             Set<String> adminRealms, SearchCond searchCondition, int page, int itemsPerPage,
             List<OrderByClause> orderBy, AnyTypeKind kind);
 
@@ -79,5 +79,5 @@ public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
      * @param <T> any
      * @return true if any matches searchCondition
      */
-    <T extends Any<?, ?, ?>> boolean matches(T any, SearchCond searchCondition, AnyTypeKind kind);
+    <T extends Any<?, ?>> boolean matches(T any, SearchCond searchCondition, AnyTypeKind kind);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
index a72937c..aeabe23 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
@@ -21,13 +21,16 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 
 public interface ExternalResourceDAO extends DAO<ExternalResource, String> {
 
     ExternalResource find(String key);
 
+    Provision findProvision(Long key);
+
     List<ExternalResource> findByPolicy(Policy policy);
 
     List<ExternalResource> findWithoutPolicy(PolicyType type);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
deleted file mode 100644
index b62cb87..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
+++ /dev/null
@@ -1,35 +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.persistence.api.dao;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public interface VirAttrDAO extends DAO<VirAttr<?>, Long> {
-
-    <T extends VirAttr<?>> T find(Long key, Class<T> reference);
-
-    <T extends VirAttr<?>> List<T> findAll(Class<T> reference);
-
-    <T extends VirAttr<?>> T save(T virtualAttribute);
-
-    <T extends VirAttr<?>> void delete(Long key, Class<T> reference);
-
-    <T extends VirAttr<?>> void delete(T virAttr);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
index 2bcd81c..9479428 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
@@ -18,8 +18,12 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Attr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 
-public interface VirSchemaDAO extends SchemaDAO<VirSchema, VirAttr<?>> {
+public interface VirSchemaDAO extends SchemaDAO<VirSchema, Attr<VirSchema, ?>> {
+
+    List<VirSchema> findByProvision(Provision provision);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
index 0384db7..f56485e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
@@ -22,7 +22,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import java.util.List;
 import java.util.Set;
 
-public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>> extends AnnotatedEntity<Long> {
+public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>> extends AnnotatedEntity<Long> {
 
     AnyType getType();
 
@@ -56,14 +56,6 @@ public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends Vir
 
     List<? extends D> getDerAttrs();
 
-    boolean add(V virAttr);
-
-    boolean remove(V virAttr);
-
-    V getVirAttr(String virSchemaName);
-
-    List<? extends V> getVirAttrs();
-
     boolean add(ExternalResource resource);
 
     boolean remove(ExternalResource resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
index 8c64086..702e7a6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
@@ -26,7 +26,7 @@ public interface AnyUtils {
 
     AnyTypeKind getAnyTypeKind();
 
-    <T extends Any<?, ?, ?>> Class<T> anyClass();
+    <T extends Any<?, ?>> Class<T> anyClass();
 
     <T extends PlainAttr<?>> Class<T> plainAttrClass();
 
@@ -44,10 +44,6 @@ public interface AnyUtils {
 
     <T extends DerAttr<?>> T newDerAttr();
 
-    <T extends VirAttr<?>> Class<T> virAttrClass();
-
-    <T extends VirAttr<?>> T newVirAttr();
-
     IntMappingType plainIntMappingType();
 
     IntMappingType derIntMappingType();

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
index 2e2a49e..d64e7e1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
@@ -26,5 +26,5 @@ public interface AnyUtilsFactory {
 
     AnyUtils getInstance(String anyTypeKind);
 
-    AnyUtils getInstance(Any<?, ?, ?> any);
+    AnyUtils getInstance(Any<?, ?> any);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
index 2be01e9..500b835 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-public interface Attr<S extends Schema, O extends Any<?, ?, ?>> extends Entity<Long> {
+public interface Attr<S extends Schema, O extends Any<?, ?>> extends Entity<Long> {
 
     O getOwner();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DerAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DerAttr.java
index 9eb3b7a..ff15a4a 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DerAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DerAttr.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.Collection;
 
-public interface DerAttr<O extends Any<?, ?, ?>> extends Attr<DerSchema, O> {
+public interface DerAttr<O extends Any<?, ?>> extends Attr<DerSchema, O> {
 
     String getValue(Collection<? extends PlainAttr<?>> attrs);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynGroupMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynGroupMembership.java
index b01fe70..ebb7cf8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynGroupMembership.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynGroupMembership.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 
-public interface DynGroupMembership<A extends Any<?, ?, ?>> extends DynMembership<A> {
+public interface DynGroupMembership<A extends Any<?, ?>> extends DynMembership<A> {
 
     Group getGroup();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
index ba0a62f..24c6309 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 
-public interface DynMembership<A extends Any<?, ?, ?>> extends Entity<Long> {
+public interface DynMembership<A extends Any<?, ?>> extends Entity<Long> {
 
     String getFIQLCond();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
index 55ac640..9d1466c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 
-public interface Membership<L extends Any<?, ?, ?>> extends Relationship<L, Group> {
+public interface Membership<L extends Any<?, ?>> extends Relationship<L, Group> {
 
     @Override
     MembershipType getType();

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
index b149851..8d8a7c1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 
-public interface PlainAttr<O extends Any<?, ?, ?>> extends Attr<PlainSchema, O> {
+public interface PlainAttr<O extends Any<?, ?>> extends Attr<PlainSchema, O> {
 
     void add(String value, AnyUtils anyUtils);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
index 0549714..b87563e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-public interface Relationship<L extends Any<?, ?, ?>, R extends Any<?, ?, ?>> extends Entity<Long> {
+public interface Relationship<L extends Any<?, ?>, R extends Any<?, ?>> extends Entity<Long> {
 
     RelationshipType getType();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
deleted file mode 100644
index 7761d93..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.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.persistence.api.entity;
-
-import java.util.List;
-
-public interface VirAttr<O extends Any<?, ?, ?>> extends Attr<VirSchema, O> {
-
-    List<String> getValues();
-
-    boolean add(String value);
-
-    boolean remove(String value);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java
index 8b796c4..65cc11d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java
@@ -18,7 +18,20 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+
 public interface VirSchema extends Schema {
 
     void setReadonly(boolean readonly);
+
+    Provision getProvision();
+
+    void setProvision(Provision provision);
+
+    String getExtAttrName();
+
+    void setExtAttrName(String extAttrName);
+
+    MappingItem asLinkingMappingItem();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AVirAttr.java
deleted file mode 100644
index be86c59..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AVirAttr.java
+++ /dev/null
@@ -1,25 +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.persistence.api.entity.anyobject;
-
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public interface AVirAttr extends VirAttr<AnyObject> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
index 2094269..1e10257 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
@@ -23,7 +23,7 @@ import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 
-public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
+public interface AnyObject extends Any<APlainAttr, ADerAttr> {
 
     boolean add(ARelationship relationship);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
index 2b6e424..f4ca14d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
@@ -21,9 +21,8 @@ package org.apache.syncope.core.persistence.api.entity.conf;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
 
-public interface Conf extends Any<CPlainAttr, DerAttr<?>, VirAttr<?>> {
+public interface Conf extends Any<CPlainAttr, DerAttr<?>> {
 
     void setKey(Long key);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
deleted file mode 100644
index 1847794..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
+++ /dev/null
@@ -1,25 +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.persistence.api.entity.group;
-
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public interface GVirAttr extends VirAttr<Group> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
index cb6008e..0afddba 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
@@ -25,7 +25,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembers
 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
-public interface Group extends Any<GPlainAttr, GDerAttr, GVirAttr> {
+public interface Group extends Any<GPlainAttr, GDerAttr> {
 
     String getName();
 
@@ -63,18 +63,6 @@ public interface Group extends Any<GPlainAttr, GDerAttr, GVirAttr> {
     @Override
     List<? extends GDerAttr> getDerAttrs();
 
-    @Override
-    boolean add(GVirAttr attr);
-
-    @Override
-    boolean remove(GVirAttr virAttr);
-
-    @Override
-    GVirAttr getVirAttr(String virSchemaName);
-
-    @Override
-    List<? extends GVirAttr> getVirAttrs();
-
     ADynGroupMembership getADynMembership();
 
     void setADynMembership(ADynGroupMembership aDynMembership);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9cd92305/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
index db9e5a3..2d19436 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
@@ -54,6 +54,10 @@ public interface PropagationTask extends Task {
 
     void setAnyTypeKind(AnyTypeKind anyTypeKind);
 
+    String getAnyType();
+
+    void setAnyType(String anyType);
+
     ExternalResource getResource();
 
     void setResource(ExternalResource resource);