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 2022/07/14 13:37:04 UTC

[syncope] branch master updated: [SYNCOPE-1689] Consolidate Provision, Mapping and Items into single JSON column (#360)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new e702a66703 [SYNCOPE-1689] Consolidate Provision, Mapping and Items into single JSON column (#360)
e702a66703 is described below

commit e702a667035b32585f45ed72cee5dc68a515219d
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Thu Jul 14 15:36:59 2022 +0200

    [SYNCOPE-1689] Consolidate Provision, Mapping and Items into single JSON column (#360)
---
 .../client/console/commons/IdMStatusProvider.java  |   8 +-
 .../client/console/panels/ConnObjectDetails.java   |   6 +-
 .../console/panels/ConnObjectListViewPanel.java    |  24 +-
 .../syncope/client/console/panels/ConnObjects.java |   8 +-
 .../console/panels/ProvisionAuxClassesPanel.java   |   6 +-
 .../console/panels/ResourceDirectoryPanel.java     |   6 -
 .../panels/search/ConnObjectSearchPanel.java       |   4 +-
 .../client/console/rest/ConnectorRestClient.java   |  16 +-
 .../client/console/rest/ResourceRestClient.java    |  12 +-
 .../console/status/LinkedAccountStatusPanel.java   |   4 +-
 .../client/console/status/ReconStatusPanel.java    |   4 +-
 .../client/console/status/ResourceStatusModal.java |   4 +-
 .../console/topology/TopologyTogglePanel.java      |  16 +-
 .../wizards/any/LinkedAccountDetailsPanel.java     |   6 +-
 .../wizards/resources/ConnectorConfPanel.java      |   6 +-
 .../wizards/resources/ConnectorDetailsPanel.java   |  16 +-
 .../wizards/resources/ConnectorWizardBuilder.java  |  12 +-
 .../wizards/resources/ProvisionWizardBuilder.java  |  11 +-
 .../wizards/resources/ResourceProvision.java       |  58 ++-
 .../wizards/resources/ResourceProvisionPanel.java  |   6 +-
 .../ui/commons/status/ConnObjectWrapper.java       |   8 +-
 .../client/ui/commons/status/StatusUtils.java      |  10 +-
 .../console/commons/IdRepoStatusProvider.java      |   6 +-
 .../client/console/commons/StatusProvider.java     |   6 +-
 .../client/console/panels/AnyDirectoryPanel.java   |   4 +-
 .../syncope/client/console/panels/Realm.java       |   6 +-
 .../client/console/panels/RemoteObjectPanel.java   |   4 +-
 .../repeater/data/table/ConnObjectAttrColumn.java  |   8 +-
 .../console/widgets/ItemTransformerWidget.java     |   6 +-
 .../console/widgets/JEXLTransformerWidget.java     |   6 +-
 .../console/wizards/any/ConnObjectPanel.java       |   4 +-
 .../client/console/wizards/any/StatusPanel.java    |  20 +-
 .../wizards/mapping/AbstractMappingPanel.java      |  12 +-
 .../mapping/ItemTransformersTogglePanel.java       |   6 +-
 .../mapping/JEXLTransformersTogglePanel.java       |   4 +-
 .../implementations/MyItemTransformer.groovy       |   6 +-
 .../console/implementations/MyLogicActions.groovy  |  13 +-
 .../implementations/MyPropagationActions.groovy    |   4 +-
 .../implementations/MyProvisionSorter.groovy       |   8 +-
 .../console/implementations/MyPullActions.groovy   |   4 +-
 .../implementations/MyPullCorrelationRule.groovy   |   2 +-
 .../implementations/MyPushCorrelationRule.groovy   |   9 +-
 .../console/implementations/MyReportlet.groovy     |   3 +-
 .../implementations/MySchedTaskJobDelegate.groovy  |  15 +-
 .../apache/syncope/common/lib/to/AttrRepoTO.java   |   4 +-
 .../apache/syncope/common/lib/to/AuthModuleTO.java |   4 +-
 .../to/{ConnBundleTO.java => ConnIdBundle.java}    |   2 +-
 ...IdObjectClassTO.java => ConnIdObjectClass.java} |   2 +-
 .../common/lib/to/{MappingTO.java => Mapping.java} |  50 +--
 .../common/lib/to/{OrgUnitTO.java => OrgUnit.java} |  88 +---
 ...ectTOResult.java => PagedConnObjectResult.java} |   8 +-
 .../lib/to/{ProvisionTO.java => Provision.java}    |  25 +-
 .../apache/syncope/common/lib/to/ReconStatus.java  |  12 +-
 .../apache/syncope/common/lib/to/ResourceTO.java   |  12 +-
 .../common/rest/api/service/ConnectorService.java  |   8 +-
 .../common/rest/api/service/ResourceService.java   |   8 +-
 .../lib/to/{ConnObjectTO.java => ConnObject.java}  |   4 +-
 .../common/lib/to/{ItemTO.java => Item.java}       |  19 +-
 .../to/{ConnObjectTO.java => ItemContainer.java}   |  63 +--
 .../syncope/common/lib/to/ItemContainerTO.java     |  33 --
 .../syncope/common/lib/to/PropagationStatus.java   |  12 +-
 .../syncope/common/lib/SerializationTest.java      |   4 +-
 core/idm/logic/pom.xml                             |   5 +
 .../apache/syncope/core/logic/ConnectorLogic.java  |  16 +-
 .../syncope/core/logic/ReconciliationLogic.java    | 240 ++++++-----
 .../apache/syncope/core/logic/ResourceLogic.java   | 132 +++---
 .../core/logic/ReconciliationLogicTest.java        |   5 +-
 .../syncope/core/logic/ResourceLogicTest.java      | 229 ++++++++++
 .../rest/cxf/service/ConnectorServiceImpl.java     |   8 +-
 .../core/rest/cxf/service/ResourceServiceImpl.java |  12 +-
 .../syncope/core/logic/ImplementationLogic.java    |   2 +-
 .../validation/InvalidEntityException.java         |   4 +-
 .../syncope/core/persistence/api/dao/AnyDAO.java   |   2 +-
 .../core/persistence/api/dao/AnyObjectDAO.java     |   2 +-
 .../syncope/core/persistence/api/dao/DAO.java      |   2 -
 .../persistence/api/dao/ExternalResourceDAO.java   |   8 +-
 .../core/persistence/api/dao/PolicyDAO.java        |   2 +-
 .../persistence/api/dao/PullCorrelationRule.java   |   2 +-
 .../persistence/api/dao/PushCorrelationRule.java   |   6 +-
 .../syncope/core/persistence/api/dao/RealmDAO.java |   2 +-
 .../syncope/core/persistence/api/dao/TaskDAO.java  |   2 +-
 .../syncope/core/persistence/api/dao/UserDAO.java  |   2 +-
 .../core/persistence/api/dao/VirSchemaDAO.java     |   6 +-
 .../syncope/core/persistence/api/entity/Any.java   |   1 -
 .../core/persistence/api/entity/AnyUtils.java      |   1 -
 .../core/persistence/api/entity/ConnInstance.java  |   1 -
 .../entity/{resource => }/ExternalResource.java    |  18 +-
 .../persistence/api/entity/LinkingMappingItem.java | 143 -------
 .../syncope/core/persistence/api/entity/Realm.java |   1 -
 .../core/persistence/api/entity/VirSchema.java     |  23 +-
 .../core/persistence/api/entity/am/AttrRepo.java   |   5 +-
 .../persistence/api/entity/am/AttrRepoItem.java    |  28 --
 .../core/persistence/api/entity/am/AuthModule.java |   5 +-
 .../persistence/api/entity/am/AuthModuleItem.java  |  28 --
 .../api/entity/policy/AccountPolicy.java           |   2 +-
 .../persistence/api/entity/policy/PullPolicy.java  |   3 +-
 .../persistence/api/entity/policy/PushPolicy.java  |   3 +-
 .../core/persistence/api/entity/resource/Item.java |  63 ---
 .../persistence/api/entity/resource/Mapping.java   |  42 --
 .../api/entity/resource/MappingItem.java           |  27 --
 .../persistence/api/entity/resource/OrgUnit.java   |  58 ---
 .../api/entity/resource/OrgUnitItem.java           |  26 --
 .../persistence/api/entity/resource/Provision.java |  64 ---
 .../api/entity/task/PropagationTask.java           |   2 +-
 .../api/entity/task/ProvisioningTask.java          |   2 +-
 .../core/persistence/api/entity/task/PullTask.java |   3 +-
 .../persistence/api/entity/user/LinkedAccount.java |   2 +-
 .../src/test/resources/domains/MasterContent.xml   | 475 ++++----------------
 .../core/persistence/jpa/dao/AbstractAnyDAO.java   |   2 +-
 .../core/persistence/jpa/dao/AbstractDAO.java      |   5 -
 .../jpa/dao/DefaultPullCorrelationRule.java        |   8 +-
 .../jpa/dao/DefaultPushCorrelationRule.java        |   6 +-
 .../core/persistence/jpa/dao/JPAAnyObjectDAO.java  |   2 +-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java    |   5 +-
 .../core/persistence/jpa/dao/JPAAttrRepoDAO.java   |   1 +
 .../core/persistence/jpa/dao/JPAAuthModuleDAO.java |   1 +
 .../persistence/jpa/dao/JPAConnInstanceDAO.java    |   1 +
 .../jpa/dao/JPAExternalResourceDAO.java            |  88 ++--
 .../persistence/jpa/dao/JPAImplementationDAO.java  |   1 -
 .../core/persistence/jpa/dao/JPAPolicyDAO.java     |   2 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java      |   2 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java       |   2 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java       |   2 +-
 .../core/persistence/jpa/dao/JPAVirSchemaDAO.java  |  66 ++-
 .../entity/{resource => }/AbstractAnyTemplate.java |   4 +-
 .../jpa/entity/JPAAnyTemplateRealm.java            |   2 -
 .../core/persistence/jpa/entity/JPAAnyUtils.java   |   2 +-
 .../persistence/jpa/entity/JPAConnInstance.java    |  58 ++-
 .../persistence/jpa/entity/JPAEntityFactory.java   |  35 +-
 .../entity/{resource => }/JPAExternalResource.java | 119 +++---
 .../core/persistence/jpa/entity/JPARealm.java      |   3 +-
 .../core/persistence/jpa/entity/JPAVirSchema.java  |  39 +-
 .../persistence/jpa/entity/am/JPAAttrRepo.java     |  57 ++-
 .../persistence/jpa/entity/am/JPAAttrRepoItem.java |  94 ----
 .../persistence/jpa/entity/am/JPAAuthModule.java   |  58 ++-
 .../jpa/entity/am/JPAAuthModuleItem.java           |  94 ----
 .../jpa/entity/anyobject/JPAAnyObject.java         |   4 +-
 .../persistence/jpa/entity/group/JPAGroup.java     |   4 +-
 .../jpa/entity/policy/JPAAccountPolicy.java        |   4 +-
 .../jpa/entity/policy/JPAPullPolicy.java           |   5 +-
 .../jpa/entity/policy/JPAPushPolicy.java           |   5 +-
 .../jpa/entity/resource/AbstractItem.java          | 158 -------
 .../jpa/entity/resource/JPAMapping.java            |  98 -----
 .../jpa/entity/resource/JPAMappingItem.java        |  83 ----
 .../jpa/entity/resource/JPAOrgUnit.java            | 146 -------
 .../jpa/entity/resource/JPAOrgUnitItem.java        |  88 ----
 .../jpa/entity/resource/JPAProvision.java          | 181 --------
 .../jpa/entity/task/AbstractProvisioningTask.java  |   4 +-
 .../jpa/entity/task/JPAAnyTemplatePullTask.java    |   3 +-
 .../jpa/entity/task/JPAPropagationTask.java        |   4 +-
 .../persistence/jpa/entity/task/JPAPullTask.java   |   5 +-
 .../jpa/entity/user/JPALinkedAccount.java          |   4 +-
 .../core/persistence/jpa/entity/user/JPAUser.java  |   4 +-
 .../entity/ExternalResourceValidator.java          |  43 +-
 .../syncope/core/persistence/jpa/AbstractTest.java |   2 +
 .../persistence/jpa/DummyConnectorManager.java     |   2 +-
 .../core/persistence/jpa/inner/AttrRepoTest.java   |  14 +-
 .../core/persistence/jpa/inner/AuthModuleTest.java |  16 +-
 .../core/persistence/jpa/inner/PolicyTest.java     |  12 +-
 .../core/persistence/jpa/inner/ResourceTest.java   | 125 +++---
 .../core/persistence/jpa/inner/TaskTest.java       |   2 +-
 .../core/persistence/jpa/inner/VirSchemaTest.java  |  14 +-
 .../persistence/jpa/outer/ConnInstanceTest.java    |   2 +-
 .../core/persistence/jpa/outer/GroupTest.java      |   9 +-
 .../persistence/jpa/outer/PlainSchemaTest.java     |  33 +-
 .../core/persistence/jpa/outer/ResourceTest.java   |  98 +----
 .../core/persistence/jpa/outer/RoleTest.java       |   7 +-
 .../core/persistence/jpa/outer/TaskTest.java       |   2 +-
 .../core/persistence/jpa/outer/UserTest.java       |   9 +-
 .../core/persistence/jpa/outer/VirSchemaTest.java  |  25 +-
 .../src/test/resources/domains/MasterContent.xml   | 476 ++++-----------------
 .../src/test/resources/domains/TwoContent.xml      |   7 +-
 .../core/provisioning/api/ConnectorManager.java    |   2 +-
 .../core/provisioning/api/MappingManager.java      |  25 +-
 .../core/provisioning/api/ProvisionSorter.java     |   3 +-
 .../provisioning/api/data/ItemTransformer.java     |   2 +-
 .../provisioning/api/data/ResourceDataBinder.java  |   2 +-
 .../api/propagation/PropagationActions.java        |   4 +-
 .../api/propagation/PropagationManager.java        |   8 +-
 .../api/propagation/PropagationTaskInfo.java       |   2 +-
 .../provisioning/api/pushpull/PullActions.java     |   8 +-
 .../api/pushpull/SyncopePullExecutor.java          |   5 +-
 .../api/pushpull/SyncopeSinglePullExecutor.java    |   4 +-
 .../api/pushpull/SyncopeSinglePushExecutor.java    |   5 +-
 .../api/pushpull/UserPushResultHandler.java        |   2 +-
 .../api/propagation/PropagationTaskInfoTest.java   |   2 +-
 .../provisioning/java/DefaultConnectorManager.java |   2 +-
 .../provisioning/java/DefaultMappingManager.java   | 108 +++--
 .../provisioning/java/DefaultVirAttrHandler.java   |  38 +-
 .../provisioning/java/ProvisioningContext.java     |   6 +
 .../java/data/AbstractAnyDataBinder.java           |  71 +--
 .../java/data/AnyObjectDataBinderImpl.java         |   4 +-
 .../java/data/AttrRepoDataBinderImpl.java          |  15 +-
 .../java/data/AuthModuleDataBinderImpl.java        |  15 +-
 .../java/data/GroupDataBinderImpl.java             |   4 +-
 .../java/data/JEXLItemTransformerImpl.java         |   2 +-
 .../java/data/PolicyDataBinderImpl.java            |   8 +-
 .../java/data/RealmDataBinderImpl.java             |   2 +-
 .../java/data/ResourceDataBinderImpl.java          | 214 ++++-----
 .../java/data/SchemaDataBinderImpl.java            |  13 +-
 .../provisioning/java/data/TaskDataBinderImpl.java |   4 +-
 .../provisioning/java/data/UserDataBinderImpl.java |  22 +-
 .../java/job/report/ReconciliationReportlet.java   |  17 +-
 .../AbstractPropagationTaskExecutor.java           |  23 +-
 .../propagation/DefaultPropagationManager.java     |  35 +-
 .../java/propagation/DeletingLinkedAccount.java    |   2 +-
 .../LDAPMembershipPropagationActions.java          |  17 +-
 .../PriorityPropagationTaskExecutor.java           |   3 +
 .../pushpull/AbstractProvisioningJobDelegate.java  |  14 +-
 .../java/pushpull/AbstractPullResultHandler.java   | 169 ++++----
 .../java/pushpull/AbstractPushResultHandler.java   |  18 +-
 .../java/pushpull/DefaultProvisionSorter.java      |  12 +-
 .../pushpull/DefaultRealmPullResultHandler.java    |  14 +-
 .../pushpull/DefaultRealmPushResultHandler.java    |  13 +-
 .../pushpull/DefaultUserPullResultHandler.java     |  36 +-
 .../pushpull/DefaultUserPushResultHandler.java     |   3 +-
 .../provisioning/java/pushpull/InboundMatcher.java |  83 ++--
 .../java/pushpull/LDAPMembershipPullActions.java   |   6 +-
 .../java/pushpull/LDAPPasswordPullActions.java     |   4 +-
 .../java/pushpull/OutboundMatcher.java             |  64 +--
 .../java/pushpull/PullJobDelegate.java             |  78 ++--
 .../java/pushpull/PushJobDelegate.java             |  19 +-
 .../java/pushpull/SinglePullJobDelegate.java       |  28 +-
 .../java/pushpull/SinglePushJobDelegate.java       |  26 +-
 .../stream/StreamAnyObjectPushResultHandler.java   |   8 +-
 .../stream/StreamGroupPushResultHandler.java       |   8 +-
 .../pushpull/stream/StreamPullJobDelegate.java     |  32 +-
 .../pushpull/stream/StreamPushJobDelegate.java     |  30 +-
 .../stream/StreamUserPushResultHandler.java        |   8 +-
 .../provisioning/java/utils/ConnObjectUtils.java   |  73 ++--
 .../core/provisioning/java/utils/MappingUtils.java |  23 +-
 .../java/DefaultMappingManagerTest.java            |  10 +-
 .../java/data/ResourceDataBinderTest.java          |  39 +-
 .../pushpull/LDAPMembershipPullActionsTest.java    |  15 +-
 .../core/spring/security/AuthDataAccessor.java     |   8 +-
 .../spring/security/DefaultPasswordGenerator.java  |   2 +-
 .../core/spring/security/PasswordGenerator.java    |   2 +-
 .../syncope/common/lib/to/OIDCC4UIProviderTO.java  |  40 +-
 .../apache/syncope/core/logic/OIDCC4UILogic.java   |   4 +-
 .../syncope/core/logic/OIDCC4UILogicContext.java   |   5 +-
 .../syncope/core/logic/OIDCC4UIProviderLogic.java  |   8 +-
 .../syncope/core/logic/oidc/OIDCUserManager.java   |  20 +-
 .../persistence/api/entity/OIDCC4UIProvider.java   |   9 +-
 .../api/entity/OIDCC4UIProviderItem.java           |  29 --
 .../jpa/dao/JPAOIDCC4UIProviderDAO.java            |   1 +
 .../jpa/entity/JPAOIDCC4UIEntityFactory.java       |   3 -
 .../jpa/entity/JPAOIDCC4UIProvider.java            |  64 ++-
 .../jpa/entity/JPAOIDCC4UIProviderItem.java        |  83 ----
 .../jpa/entity/JPAOIDCC4UIUserTemplate.java        |   1 -
 .../entity/OIDCC4UIProviderValidator.java          |  25 +-
 .../java/data/OIDCC4UIProviderDataBinderImpl.java  |  39 +-
 .../console/wizards/SAML2IdPWizardBuilder.java     |   4 +-
 .../syncope/common/lib/to/SAML2SP4UIIdPTO.java     |  35 +-
 .../syncope/core/logic/SAML2SP4UIIdPLogic.java     |   4 +-
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |   4 +-
 .../syncope/core/logic/SAML2SP4UILogicContext.java |   5 +-
 .../syncope/core/logic/saml2/SAML2ClientCache.java |   4 +-
 .../core/logic/saml2/SAML2SP4UIUserManager.java    |  19 +-
 .../core/persistence/api/entity/SAML2SP4UIIdP.java |   9 +-
 .../persistence/api/entity/SAML2SP4UIIdPItem.java  |  28 --
 .../persistence/jpa/dao/JPASAML2SP4UIIdPDAO.java   |   1 +
 .../jpa/entity/JPASAML2SP4UIEntityFactory.java     |   3 -
 .../persistence/jpa/entity/JPASAML2SP4UIIdP.java   |  63 ++-
 .../jpa/entity/JPASAML2SP4UIIdPItem.java           |  83 ----
 .../jpa/entity/JPASAML2SP4UIUserTemplate.java      |   1 -
 .../validation/entity/SAML2SP4UIIdPValidator.java  |  27 +-
 .../java/data/SAML2SP4UIIdPDataBinderImpl.java     |  32 +-
 .../core/reference/DateToDateItemTransformer.java  |   2 +-
 .../core/reference/DateToLongItemTransformer.java  |   2 +-
 .../core/reference/DummyPullCorrelationRule.java   |   2 +-
 .../core/reference/DummyPushCorrelationRule.java   |   5 +-
 .../LinkedAccountSamplePullCorrelationRule.java    |   2 +-
 .../apache/syncope/fit/core/AnyObjectITCase.java   |   4 +-
 .../apache/syncope/fit/core/AttrRepoITCase.java    |   6 +-
 .../apache/syncope/fit/core/AuthModuleITCase.java  |   6 +-
 .../apache/syncope/fit/core/ConnectorITCase.java   |  22 +-
 .../syncope/fit/core/ExceptionMapperITCase.java    |   4 +-
 .../org/apache/syncope/fit/core/GroupITCase.java   |  22 +-
 .../syncope/fit/core/LinkedAccountITCase.java      |   6 +-
 .../apache/syncope/fit/core/MembershipITCase.java  |   4 +-
 .../syncope/fit/core/MultitenancyITCase.java       |  18 +-
 .../syncope/fit/core/PropagationTaskITCase.java    |  48 +--
 .../apache/syncope/fit/core/PullTaskITCase.java    |  26 +-
 .../apache/syncope/fit/core/PushTaskITCase.java    |  12 +-
 .../apache/syncope/fit/core/ResourceITCase.java    | 131 +++---
 .../org/apache/syncope/fit/core/SearchITCase.java  |   6 +-
 .../org/apache/syncope/fit/core/UserITCase.java    |  10 +-
 .../apache/syncope/fit/core/UserIssuesITCase.java  |  46 +-
 .../org/apache/syncope/fit/core/VirAttrITCase.java |  30 +-
 .../syncope/fit/core/wa/WAClientAppITCase.java     |   6 +-
 .../test/resources/PrefixItemTransformer.groovy    |   2 +-
 .../src/test/resources/TestPullRule.groovy         |   6 +-
 .../src/test/resources/TestPushRule.groovy         |  17 +-
 .../org/apache/syncope/fit/ui/OIDC4UIITCase.java   |  14 +-
 .../apache/syncope/fit/ui/SAML2SP4UIITCase.java    |  14 +-
 295 files changed, 2785 insertions(+), 4822 deletions(-)

diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
index 9766b7f0a5..88384af758 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMStatusProvider.java
@@ -30,7 +30,7 @@ import org.apache.syncope.client.console.status.ReconStatusUtils;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.ui.commons.status.ConnObjectWrapper;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 
 public class IdMStatusProvider implements StatusProvider {
@@ -38,7 +38,7 @@ public class IdMStatusProvider implements StatusProvider {
     private static final long serialVersionUID = 1875374599950896631L;
 
     @Override
-    public Optional<Pair<ConnObjectTO, ConnObjectTO>> get(
+    public Optional<Pair<ConnObject, ConnObject>> get(
             final String anyTypeKey, final String connObjectKeyValue, final String resource) {
 
         return ReconStatusUtils.getReconStatus(anyTypeKey, connObjectKeyValue, resource).
@@ -46,12 +46,12 @@ public class IdMStatusProvider implements StatusProvider {
     }
 
     @Override
-    public List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(
+    public List<Triple<ConnObject, ConnObjectWrapper, String>> get(
             final AnyTO any, final Collection<String> resources) {
 
         return ReconStatusUtils.getReconStatuses(
                 any.getType(), any.getKey(), any.getResources()).stream().
-                map(status -> Triple.<ConnObjectTO, ConnObjectWrapper, String>of(
+                map(status -> Triple.<ConnObject, ConnObjectWrapper, String>of(
                 status.getRight().getOnSyncope(),
                 new ConnObjectWrapper(any, status.getLeft(), status.getRight().getOnResource()),
                 null)).
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectDetails.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectDetails.java
index 4f348bea33..8cea28186c 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectDetails.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectDetails.java
@@ -20,7 +20,7 @@ package org.apache.syncope.client.console.panels;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.wizards.any.ConnObjectPanel;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 
@@ -28,14 +28,14 @@ public class ConnObjectDetails extends MultilevelPanel.SecondLevel {
 
     private static final long serialVersionUID = -6532127408741991806L;
 
-    public ConnObjectDetails(final ConnObjectTO connObjectTO) {
+    public ConnObjectDetails(final ConnObject connObjectTO) {
         super();
 
         MultilevelPanel mlp = new MultilevelPanel("details");
         mlp.setFirstLevel(new ConnObjectPanel(
                 MultilevelPanel.FIRST_LEVEL_ID,
                 Pair.<IModel<?>, IModel<?>>of(Model.of(), Model.of()),
-                Pair.of((ConnObjectTO) null, connObjectTO),
+                Pair.of((ConnObject) null, connObjectTO),
                 true));
         add(mlp);
     }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
index 24875279f1..a4d24cb6b0 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjectListViewPanel.java
@@ -47,7 +47,7 @@ import org.apache.syncope.client.ui.commons.status.StatusUtils;
 import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.ReconStatus;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -148,15 +148,15 @@ public abstract class ConnObjectListViewPanel extends Panel {
         accordion.setOutputMarkupId(true);
         add(accordion.setEnabled(true).setVisible(true));
 
-        List<ConnObjectTO> listOfItems = reloadItems(resource.getKey(), anyType, null, null);
+        List<ConnObject> listOfItems = reloadItems(resource.getKey(), anyType, null, null);
 
-        ListViewPanel.Builder<ConnObjectTO> builder = new ListViewPanel.Builder<>(
-                ConnObjectTO.class, pageRef) {
+        ListViewPanel.Builder<ConnObject> builder = new ListViewPanel.Builder<>(
+                ConnObject.class, pageRef) {
 
             private static final long serialVersionUID = -8251750413385566738L;
 
             @Override
-            protected Component getValueComponent(final String key, final ConnObjectTO bean) {
+            protected Component getValueComponent(final String key, final ConnObject bean) {
                 if (StringUtils.equals(key, STATUS)) {
                     ReconStatus status;
                     try {
@@ -211,7 +211,7 @@ public abstract class ConnObjectListViewPanel extends Panel {
             private static final long serialVersionUID = 7511002881490248598L;
 
             @Override
-            public void onClick(final AjaxRequestTarget target, final ConnObjectTO modelObject) {
+            public void onClick(final AjaxRequestTarget target, final ConnObject modelObject) {
                 viewConnObject(modelObject, target);
             }
         }, ActionLink.ActionType.VIEW, IdMEntitlement.RESOURCE_GET_CONNOBJECT).
@@ -228,7 +228,7 @@ public abstract class ConnObjectListViewPanel extends Panel {
                 private static final long serialVersionUID = 6377238742125L;
 
                 @Override
-                public void onClick(final AjaxRequestTarget target, final ConnObjectTO modelObject) {
+                public void onClick(final AjaxRequestTarget target, final ConnObject modelObject) {
                     try {
                         ReconStatus status = ReconciliationRestClient.status(
                                 new ReconQuery.Builder(anyType, resource.getKey()).fiql(modelObject.getFiql()).build());
@@ -265,7 +265,7 @@ public abstract class ConnObjectListViewPanel extends Panel {
 
             @Override
             public void onClick(final AjaxRequestTarget target) {
-                List<ConnObjectTO> listOfItems = reloadItems(resource.getKey(), anyType, nextPageCookie, getFiql());
+                List<ConnObject> listOfItems = reloadItems(resource.getKey(), anyType, nextPageCookie, getFiql());
                 target.add(arrows);
                 send(ConnObjectListViewPanel.this, Broadcast.DEPTH, new ListViewReload<>(listOfItems, target));
             }
@@ -282,7 +282,7 @@ public abstract class ConnObjectListViewPanel extends Panel {
         if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
             this.nextPageCookie = null;
             AjaxRequestTarget target = SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
-            List<ConnObjectTO> listOfItems = reloadItems(resource.getKey(), anyType, null, getFiql());
+            List<ConnObject> listOfItems = reloadItems(resource.getKey(), anyType, null, getFiql());
             target.add(arrows);
             send(ConnObjectListViewPanel.this, Broadcast.DEPTH, new ListViewReload<>(listOfItems, target));
         } else {
@@ -290,7 +290,7 @@ public abstract class ConnObjectListViewPanel extends Panel {
         }
     }
 
-    protected abstract void viewConnObject(ConnObjectTO connObjectTO, AjaxRequestTarget target);
+    protected abstract void viewConnObject(ConnObject connObjectTO, AjaxRequestTarget target);
 
     protected abstract void pullConnObject(
             String fiql,
@@ -301,13 +301,13 @@ public abstract class ConnObjectListViewPanel extends Panel {
             boolean isOnSyncope,
             PageReference pageRef);
 
-    protected List<ConnObjectTO> reloadItems(
+    protected List<ConnObject> reloadItems(
             final String resource,
             final String anyType,
             final String cookie,
             final String fiql) {
 
-        Pair<String, List<ConnObjectTO>> items = new ResourceRestClient().searchConnObjects(
+        Pair<String, List<ConnObject>> items = new ResourceRestClient().searchConnObjects(
                 resource,
                 anyType,
                 new ConnObjectTOQuery.Builder().
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
index c59e49af4d..17f8b11c95 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ConnObjects.java
@@ -27,8 +27,8 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.ui.commons.panels.ModalPanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -51,7 +51,7 @@ public class ConnObjects extends Panel implements ModalPanel {
         super(BaseModal.CONTENT_ID);
 
         List<String> availableAnyTypes = resource.getProvisions().stream().
-                map(ProvisionTO::getAnyType).
+                map(Provision::getAnyType).
                 sorted(AnyTypeRestClient.KEY_COMPARATOR).
                 collect(Collectors.toList());
         if (resource.getOrgUnit() != null) {
@@ -115,7 +115,7 @@ public class ConnObjects extends Panel implements ModalPanel {
         }
 
         @Override
-        protected void viewConnObject(final ConnObjectTO connObjectTO, final AjaxRequestTarget target) {
+        protected void viewConnObject(final ConnObject connObjectTO, final AjaxRequestTarget target) {
             anyTypes.setEnabled(false);
             target.add(anyTypes);
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
index d2844bb8b4..96c8637017 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ProvisionAuxClassesPanel.java
@@ -30,7 +30,7 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
@@ -46,9 +46,9 @@ public class ProvisionAuxClassesPanel extends Panel {
 
     private static final Logger LOG = LoggerFactory.getLogger(ProvisionAuxClassesPanel.class);
 
-    private final ProvisionTO provision;
+    private final Provision provision;
 
-    public ProvisionAuxClassesPanel(final String id, final ProvisionTO provision) {
+    public ProvisionAuxClassesPanel(final String id, final Provision provision) {
         super(id);
         setOutputMarkupId(true);
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
index 751b22669a..f7f1a1829b 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java
@@ -346,14 +346,8 @@ public class ResourceDirectoryPanel extends
                     ResourceTO resource = ResourceRestClient.read(((ResourceTO) model.getObject()).getKey());
                     resource.setKey("Copy of " + resource.getKey());
                     // reset some resource objects keys
-                    if (resource.getOrgUnit() != null) {
-                        resource.getOrgUnit().setKey(null);
-                        resource.getOrgUnit().getItems().forEach(item -> item.setKey(null));
-                    }
                     resource.getProvisions().forEach(provision -> {
-                        provision.setKey(null);
                         if (provision.getMapping() != null) {
-                            provision.getMapping().getItems().forEach(item -> item.setKey(null));
                             provision.getMapping().getLinkingItems().clear();
                         }
                         provision.getVirSchemas().clear();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
index 3dc4f855e5..4645e47713 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/search/ConnObjectSearchPanel.java
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnIdObjectClass;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -120,7 +120,7 @@ public class ConnObjectSearchPanel extends AbstractSearchPanel {
             protected Map<String, PlainSchemaTO> load() {
                 return connectorRestClient.buildObjectClassInfo(
                         connectorRestClient.read(resource.getConnector()), false).stream().
-                        map(ConnIdObjectClassTO::getAttributes).
+                        map(ConnIdObjectClass::getAttributes).
                         flatMap(List::stream).
                         collect(Collectors.toMap(PlainSchemaTO::getKey, Function.identity(),
                                 (schema1, schema2) -> schema1));
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index 31e933ea2f..f34ef84e2a 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -33,8 +33,8 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
+import org.apache.syncope.common.lib.to.ConnIdObjectClass;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -78,7 +78,7 @@ public class ConnectorRestClient extends BaseRestClient {
                     getLanguage());
             if (connInstance != null) {
                 result.addAll(service.buildObjectClassInfo(connInstance, true).stream().
-                        map(ConnIdObjectClassTO::getType).collect(Collectors.toList()));
+                        map(ConnIdObjectClass::getType).collect(Collectors.toList()));
             }
         } catch (Exception e) {
             LOG.error("While reading object classes for connector {}", connectorKey, e);
@@ -98,7 +98,7 @@ public class ConnectorRestClient extends BaseRestClient {
         connInstanceTO.getConf().addAll(conf);
 
         // SYNCOPE-156: use provided info to give schema names (and type!) by ObjectClass
-        Optional<ConnIdObjectClassTO> connIdObjectClass = buildObjectClassInfo(connInstanceTO, false).stream().
+        Optional<ConnIdObjectClass> connIdObjectClass = buildObjectClassInfo(connInstanceTO, false).stream().
                 filter(object -> object.getType().equalsIgnoreCase(objectClass)).
                 findAny();
 
@@ -139,8 +139,8 @@ public class ConnectorRestClient extends BaseRestClient {
         return connectorTO;
     }
 
-    public static List<ConnBundleTO> getAllBundles() {
-        List<ConnBundleTO> bundles = List.of();
+    public static List<ConnIdBundle> getAllBundles() {
+        List<ConnIdBundle> bundles = List.of();
 
         try {
             bundles = getService(ConnectorService.class).getBundles(SyncopeConsoleSession.get().getLocale().toString());
@@ -205,10 +205,10 @@ public class ConnectorRestClient extends BaseRestClient {
         return Pair.of(check, errorMessage);
     }
 
-    public static List<ConnIdObjectClassTO> buildObjectClassInfo(
+    public static List<ConnIdObjectClass> buildObjectClassInfo(
             final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
 
-        List<ConnIdObjectClassTO> result = List.of();
+        List<ConnIdObjectClass> result = List.of();
         try {
             result = getService(ConnectorService.class).buildObjectClassInfo(connInstanceTO, includeSpecial);
         } catch (Exception e) {
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index ed5d3d0978..908a5ca2cf 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -29,8 +29,8 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.to.PagedConnObjectResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
@@ -75,7 +75,7 @@ public class ResourceRestClient extends BaseRestClient {
         return Pair.of(check, errorMessage);
     }
 
-    public static ConnObjectTO readConnObject(final String resource, final String anyTypeKey, final String anyKey) {
+    public static ConnObject readConnObject(final String resource, final String anyTypeKey, final String anyKey) {
         return getService(ResourceService.class).readConnObject(resource, anyTypeKey, anyKey);
     }
 
@@ -93,16 +93,16 @@ public class ResourceRestClient extends BaseRestClient {
         return null;
     }
 
-    public static Pair<String, List<ConnObjectTO>> searchConnObjects(
+    public static Pair<String, List<ConnObject>> searchConnObjects(
             final String resource,
             final String anyTypeKey,
             final ConnObjectTOQuery.Builder queryBuilder,
             final SortParam<String> sortParam) {
 
-        final List<ConnObjectTO> result = new ArrayList<>();
+        final List<ConnObject> result = new ArrayList<>();
         String nextPageResultCookie = null;
 
-        PagedConnObjectTOResult list;
+        PagedConnObjectResult list;
         try {
             if (sortParam != null) {
                 queryBuilder.orderBy(toOrderBy(sortParam));
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/LinkedAccountStatusPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/LinkedAccountStatusPanel.java
index 16904b043b..beb6146a51 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/LinkedAccountStatusPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/LinkedAccountStatusPanel.java
@@ -23,7 +23,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.panels.RemoteObjectPanel;
 import org.apache.syncope.client.console.wizards.any.ConnObjectPanel;
 import org.apache.syncope.client.ui.commons.Constants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.ReconStatus;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
@@ -56,7 +56,7 @@ public class LinkedAccountStatusPanel extends RemoteObjectPanel {
     }
 
     @Override
-    protected Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs() {
+    protected Pair<ConnObject, ConnObject> getConnObjectTOs() {
         Optional<ReconStatus> status = ReconStatusUtils.getReconStatus(anyTypeKey, connObjectKeyValue, resource);
 
         return status.map(reconStatus -> Pair.of(reconStatus.getOnSyncope(), reconStatus.getOnResource())).orElse(null);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconStatusPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconStatusPanel.java
index 3a92e5612a..5a737f7b5f 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconStatusPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconStatusPanel.java
@@ -23,7 +23,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.panels.RemoteObjectPanel;
 import org.apache.syncope.client.console.wizards.any.ConnObjectPanel;
 import org.apache.syncope.client.ui.commons.Constants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.ReconStatus;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
@@ -56,7 +56,7 @@ public class ReconStatusPanel extends RemoteObjectPanel {
     }
 
     @Override
-    protected Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs() {
+    protected Pair<ConnObject, ConnObject> getConnObjectTOs() {
         List<Pair<String, ReconStatus>> statuses =
                 ReconStatusUtils.getReconStatuses(anyTypeKey, anyKey, List.of(resource));
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
index e052cc214b..0399dc1f30 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ResourceStatusModal.java
@@ -29,7 +29,7 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.ui.commons.status.StatusBean;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -50,7 +50,7 @@ public class ResourceStatusModal extends StatusModal<ResourceTO> {
         super(baseModal, pageReference, resource, null, false);
 
         List<String> availableAnyTypes = resource.getProvisions().stream().
-                map(ProvisionTO::getAnyType).
+                map(Provision::getAnyType).
                 sorted(AnyTypeRestClient.KEY_COMPARATOR).
                 collect(Collectors.toList());
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index 8ddf0bebf9..1ca1ce27aa 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -45,8 +45,7 @@ import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
@@ -635,19 +634,8 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     ResourceTO resource = ResourceRestClient.read(node.getKey());
                     resource.setKey("Copy of " + node.getKey());
 
-                    // reset some resource objects keys
-                    if (resource.getOrgUnit() != null) {
-                        resource.getOrgUnit().setKey(null);
-                        for (ItemTO item : resource.getOrgUnit().getItems()) {
-                            item.setKey(null);
-                        }
-                    }
-                    for (ProvisionTO provision : resource.getProvisions()) {
-                        provision.setKey(null);
+                    for (Provision provision : resource.getProvisions()) {
                         if (provision.getMapping() != null) {
-                            for (ItemTO item : provision.getMapping().getItems()) {
-                                item.setKey(null);
-                            }
                             provision.getMapping().getLinkingItems().clear();
                         }
                         provision.getVirSchemas().clear();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
index 7b4d93c521..0bbe9be3c4 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java
@@ -31,7 +31,7 @@ import org.apache.syncope.client.ui.commons.ConnIdSpecialName;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.LinkedAccountTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -158,7 +158,7 @@ public class LinkedAccountDetailsPanel extends WizardStep {
         AtomicReference<String> resourceRemoteKey = new AtomicReference<>(ConnIdSpecialName.NAME);
         try {
             resourceRemoteKey.set(ResourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()).get().
-                    getMapping().getConnObjectKeyItem().getExtAttrName());
+                    getMapping().getConnObjectKeyItem().get().getExtAttrName());
         } catch (Exception ex) {
             LOG.error("While reading mapping for resource {}", resource, ex);
         }
@@ -168,7 +168,7 @@ public class LinkedAccountDetailsPanel extends WizardStep {
             builder.fiql(SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
                     is(resourceRemoteKey.get()).equalTo(searchTerm + "*").query()).build();
         }
-        Pair<String, List<ConnObjectTO>> items = ResourceRestClient.searchConnObjects(
+        Pair<String, List<ConnObject>> items = ResourceRestClient.searchConnObjects(
                 resource,
                 AnyTypeKind.USER.name(),
                 builder,
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorConfPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorConfPanel.java
index 3188230117..4574260c8d 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorConfPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorConfPanel.java
@@ -20,7 +20,7 @@ package org.apache.syncope.client.console.wizards.resources;
 
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.wicket.model.LoadableDetachableModel;
@@ -29,9 +29,9 @@ public abstract class ConnectorConfPanel extends AbstractConnConfPanel<ConnInsta
 
     private static final long serialVersionUID = -2025535531121434050L;
 
-    private final List<ConnBundleTO> bundles;
+    private final List<ConnIdBundle> bundles;
 
-    public ConnectorConfPanel(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
+    public ConnectorConfPanel(final ConnInstanceTO connInstanceTO, final List<ConnIdBundle> bundles) {
         super(connInstanceTO);
         this.bundles = bundles;
 
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
index 94492dcda2..e285ed2bc9 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorDetailsPanel.java
@@ -34,7 +34,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoiceP
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -48,7 +48,7 @@ public class ConnectorDetailsPanel extends WizardStep {
 
     private static final long serialVersionUID = -2435937897614232137L;
 
-    public ConnectorDetailsPanel(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
+    public ConnectorDetailsPanel(final ConnInstanceTO connInstanceTO, final List<ConnIdBundle> bundles) {
         super();
         setOutputMarkupId(true);
 
@@ -111,7 +111,7 @@ public class ConnectorDetailsPanel extends WizardStep {
                     ((DropDownChoice<String>) location.getField()).setNullValid(false);
                     bundleName.setEnabled(true);
 
-                    List<ConnBundleTO> bundles = ConnectorRestClient.getAllBundles().stream().
+                    List<ConnIdBundle> bundles = ConnectorRestClient.getAllBundles().stream().
                             filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
                             collect(Collectors.toList());
 
@@ -161,7 +161,7 @@ public class ConnectorDetailsPanel extends WizardStep {
 
                 List<String> versions;
                 if (bundles.isEmpty()) {
-                    List<ConnBundleTO> bundles = ConnectorRestClient.getAllBundles().stream().
+                    List<ConnIdBundle> bundles = ConnectorRestClient.getAllBundles().stream().
                             filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
                             collect(Collectors.toList());
                     versions = getVersions(connInstanceTO, bundles);
@@ -207,14 +207,14 @@ public class ConnectorDetailsPanel extends WizardStep {
                 new PropertyModel<>(connInstanceTO.getPoolConf(), "minEvictableIdleTimeMillis")));
     }
 
-    private static List<String> getVersions(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
+    private static List<String> getVersions(final ConnInstanceTO connInstanceTO, final List<ConnIdBundle> bundles) {
         return bundles.stream().filter(object -> object.getLocation().equals(connInstanceTO.getLocation())
                 && object.getBundleName().equals(connInstanceTO.getBundleName())).
-                map(ConnBundleTO::getVersion).collect(Collectors.toList());
+                map(ConnIdBundle::getVersion).collect(Collectors.toList());
     }
 
-    private List<String> getBundles(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
+    private List<String> getBundles(final ConnInstanceTO connInstanceTO, final List<ConnIdBundle> bundles) {
         return bundles.stream().filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
-                map(ConnBundleTO::getBundleName).collect(Collectors.toList());
+                map(ConnIdBundle::getBundleName).collect(Collectors.toList());
     }
 }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
index 4346106169..7fc06a4dd1 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
@@ -26,7 +26,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.topology.TopologyNode;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -41,7 +41,7 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
 
     private static final long serialVersionUID = -2025535531121434050L;
 
-    private final List<ConnBundleTO> bundles;
+    private final List<ConnIdBundle> bundles;
 
     public ConnectorWizardBuilder(final ConnInstanceTO defaultItem, final PageReference pageRef) {
         super(defaultItem, pageRef);
@@ -60,7 +60,7 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
             @Override
             protected Pair<Boolean, String> check(final AjaxRequestTarget target) {
                 ConnInstanceTO connInstanceTO = ConnInstanceTO.class.cast(modelObject);
-                ConnBundleTO bundleTO = ConnectorWizardBuilder.getBundle(connInstanceTO, bundles);
+                ConnIdBundle bundleTO = ConnectorWizardBuilder.getBundle(connInstanceTO, bundles);
 
                 connInstanceTO.setConnectorName(bundleTO.getConnectorName());
                 connInstanceTO.setBundleName(bundleTO.getBundleName());
@@ -82,7 +82,7 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
     @Override
     protected Serializable onApplyInternal(final Serializable modelObject) {
         ConnInstanceTO connInstanceTO = ConnInstanceTO.class.cast(modelObject);
-        ConnBundleTO bundleTO = ConnectorWizardBuilder.getBundle(connInstanceTO, bundles);
+        ConnIdBundle bundleTO = ConnectorWizardBuilder.getBundle(connInstanceTO, bundles);
 
         connInstanceTO.setConnectorName(bundleTO.getConnectorName());
         connInstanceTO.setBundleName(bundleTO.getBundleName());
@@ -121,8 +121,8 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
                 target);
     }
 
-    protected static ConnBundleTO getBundle(final ConnInstanceTO connInstanceTO, final List<ConnBundleTO> bundles) {
-        List<ConnBundleTO> bundlesList;
+    protected static ConnIdBundle getBundle(final ConnInstanceTO connInstanceTO, final List<ConnIdBundle> bundles) {
+        List<ConnIdBundle> bundlesList;
         if (bundles.isEmpty()) {
             bundlesList = ConnectorRestClient.getAllBundles().stream().
                     filter(object -> object.getLocation().equals(connInstanceTO.getLocation())).
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
index 792ffd0673..06e70654d3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
@@ -32,8 +32,7 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.MappingTO;
-import org.apache.syncope.common.lib.to.ProvisionTO;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.wicket.PageReference;
@@ -211,7 +210,7 @@ public class ProvisionWizardBuilder extends BaseAjaxWizardBuilder<ResourceProvis
         JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
         addOuterObject(jexlTransformers);
         if (resourceProvision.getProvisionTO() != null && resourceProvision.getProvisionTO().getMapping() == null) {
-            resourceProvision.getProvisionTO().setMapping(new MappingTO());
+            resourceProvision.getProvisionTO().setMapping(new org.apache.syncope.common.lib.to.Mapping());
         }
         mapping.add(new ResourceMappingPanel(
                 "mapping", resourceTO, adminRealm, resourceProvision, itemTransformers, jexlTransformers));
@@ -230,18 +229,18 @@ public class ProvisionWizardBuilder extends BaseAjaxWizardBuilder<ResourceProvis
             this.resourceTO.getOrgUnit().getItems().clear();
             this.resourceTO.getOrgUnit().getItems().addAll(resourceProvision.getItems());
         } else if (resourceProvision.getProvisionTO() != null) {
-            final List<ProvisionTO> provisions;
+            final List<Provision> provisions;
             if (resourceProvision.getKey() == null) {
                 provisions = this.resourceTO.getProvisions().stream().
                         filter(object -> !resourceProvision.getAnyType().equals(object.getAnyType())).
                         collect(Collectors.toList());
             } else {
                 provisions = this.resourceTO.getProvisions().stream().
-                        filter(object -> !resourceProvision.getKey().equals(object.getKey())).
+                        filter(object -> !resourceProvision.getKey().equals(object.getObjectClass())).
                         collect(Collectors.toList());
             }
 
-            ProvisionTO provisionTO = resourceProvision.getProvisionTO();
+            Provision provisionTO = resourceProvision.getProvisionTO();
             provisionTO.getMapping().getItems().clear();
             provisionTO.getMapping().getItems().addAll(resourceProvision.getItems());
             provisions.add(provisionTO);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
index 747a383e54..d61cf6c6e6 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvision.java
@@ -23,38 +23,38 @@ import java.util.List;
 import java.util.Optional;
 import org.apache.syncope.client.console.panels.ToggleableTarget;
 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;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.OrgUnit;
+import org.apache.syncope.common.lib.to.Provision;
 
 public class ResourceProvision implements ToggleableTarget {
 
     private static final long serialVersionUID = 1103991919577739952L;
 
-    private ProvisionTO provisionTO;
+    private Provision provisionTO;
 
-    private OrgUnitTO orgUnitTO;
+    private OrgUnit orgUnitTO;
 
-    private List<ItemTO> items;
+    private List<Item> items;
 
     public ResourceProvision() {
         this.items = new ArrayList<>();
     }
 
-    public ResourceProvision(final ProvisionTO provisionTO) {
+    public ResourceProvision(final Provision provisionTO) {
         setProvisionTO(provisionTO);
     }
 
-    public ResourceProvision(final OrgUnitTO orgUnitTO) {
+    public ResourceProvision(final OrgUnit orgUnitTO) {
         setOrgUnitTO(orgUnitTO);
     }
 
-    public ProvisionTO getProvisionTO() {
+    public Provision getProvisionTO() {
         return provisionTO;
     }
 
-    public final void setProvisionTO(final ProvisionTO provisionTO) {
+    public final void setProvisionTO(final Provision provisionTO) {
         this.provisionTO = provisionTO;
         this.orgUnitTO = null;
 
@@ -68,11 +68,11 @@ public class ResourceProvision implements ToggleableTarget {
         }
     }
 
-    public OrgUnitTO getOrgUnitTO() {
+    public OrgUnit getOrgUnitTO() {
         return orgUnitTO;
     }
 
-    public final void setOrgUnitTO(final OrgUnitTO orgUnitTO) {
+    public final void setOrgUnitTO(final OrgUnit orgUnitTO) {
         this.orgUnitTO = orgUnitTO;
         this.provisionTO = null;
 
@@ -87,33 +87,32 @@ public class ResourceProvision implements ToggleableTarget {
     @Override
     public String getKey() {
         return provisionTO == null
-            ? Optional.ofNullable(orgUnitTO).map(OrgUnitTO::getKey).orElse(null)
-            : provisionTO.getKey();
+                ? Optional.ofNullable(orgUnitTO).map(OrgUnit::getObjectClass).orElse(null)
+                : provisionTO.getObjectClass();
     }
 
     @Override
     public String getAnyType() {
         return provisionTO == null
-            ? orgUnitTO == null
-            ? null
-            : SyncopeConstants.REALM_ANYTYPE : provisionTO.getAnyType();
+                ? orgUnitTO == null
+                        ? null
+                        : SyncopeConstants.REALM_ANYTYPE : provisionTO.getAnyType();
     }
 
     public void setAnyType(final String anyType) {
         if (SyncopeConstants.REALM_ANYTYPE.equals(anyType)) {
-            setOrgUnitTO(new OrgUnitTO());
+            setOrgUnitTO(new OrgUnit());
         } else {
-            setProvisionTO(new ProvisionTO());
+            setProvisionTO(new Provision());
             getProvisionTO().setAnyType(anyType);
-            getProvisionTO().setMapping(new MappingTO());
+            getProvisionTO().setMapping(new Mapping());
         }
     }
 
     public String getObjectClass() {
         return provisionTO == null
-            ? Optional.ofNullable(orgUnitTO)
-            .map(OrgUnitTO::getObjectClass)
-            .orElse(null) : provisionTO.getObjectClass();
+                ? Optional.ofNullable(orgUnitTO).map(OrgUnit::getObjectClass).orElse(null)
+                : provisionTO.getObjectClass();
     }
 
     public void setObjectClass(final String objectClass) {
@@ -129,8 +128,8 @@ public class ResourceProvision implements ToggleableTarget {
     }
 
     public boolean isIgnoreCaseMatch() {
-        return Optional.ofNullable(provisionTO)
-            .map(ProvisionTO::isIgnoreCaseMatch).orElseGet(() -> orgUnitTO.isIgnoreCaseMatch());
+        return Optional.ofNullable(provisionTO).
+                map(Provision::isIgnoreCaseMatch).orElseGet(() -> orgUnitTO.isIgnoreCaseMatch());
     }
 
     public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) {
@@ -143,8 +142,8 @@ public class ResourceProvision implements ToggleableTarget {
 
     public String getConnObjectLink() {
         return provisionTO == null
-            ? Optional.ofNullable(orgUnitTO).map(OrgUnitTO::getConnObjectLink).orElse(null)
-            : provisionTO.getMapping().getConnObjectLink();
+                ? Optional.ofNullable(orgUnitTO).map(OrgUnit::getConnObjectLink).orElse(null)
+                : provisionTO.getMapping().getConnObjectLink();
     }
 
     public void setConnObjectLink(final String connObjectLink) {
@@ -155,8 +154,7 @@ public class ResourceProvision implements ToggleableTarget {
         }
     }
 
-    public List<ItemTO> getItems() {
+    public List<Item> getItems() {
         return items;
     }
-
 }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
index 01f6dd2a80..3c59396028 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
@@ -39,7 +39,7 @@ import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.wicket.PageReference;
@@ -257,8 +257,8 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
         add(objectTypeTogglePanel);
     }
 
-    private void checkConnObjectKeyCount(final String anyType, final List<ItemTO> items) {
-        long connObjectKeyCount = items.stream().filter(ItemTO::isConnObjectKey).count();
+    private void checkConnObjectKeyCount(final String anyType, final List<Item> items) {
+        long connObjectKeyCount = items.stream().filter(Item::isConnObjectKey).count();
 
         if (connObjectKeyCount != 1) {
             throw new IllegalArgumentException(anyType + ": "
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/ConnObjectWrapper.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/ConnObjectWrapper.java
index 9ee0cbac5e..c5b8be70b3 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/ConnObjectWrapper.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/ConnObjectWrapper.java
@@ -20,7 +20,7 @@ package org.apache.syncope.client.ui.commons.status;
 
 import java.io.Serializable;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 
 public class ConnObjectWrapper implements Serializable {
 
@@ -30,9 +30,9 @@ public class ConnObjectWrapper implements Serializable {
 
     private final String resource;
 
-    private final ConnObjectTO connObjectTO;
+    private final ConnObject connObjectTO;
 
-    public ConnObjectWrapper(final AnyTO any, final String resource, final ConnObjectTO connObjectTO) {
+    public ConnObjectWrapper(final AnyTO any, final String resource, final ConnObject connObjectTO) {
         this.any = any;
         this.resource = resource;
         this.connObjectTO = connObjectTO;
@@ -46,7 +46,7 @@ public class ConnObjectWrapper implements Serializable {
         return resource;
     }
 
-    public ConnObjectTO getConnObjectTO() {
+    public ConnObject getConnObjectTO() {
         return connObjectTO;
     }
 
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
index 6bf24ad654..787f8eb744 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/status/StatusUtils.java
@@ -28,7 +28,7 @@ import org.apache.syncope.client.ui.commons.panels.LabelPanel;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.request.StatusR;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.wicket.markup.ComponentTag;
@@ -42,7 +42,7 @@ public final class StatusUtils implements Serializable {
     public static StatusBean getStatusBean(
             final AnyTO anyTO,
             final String resource,
-            final ConnObjectTO connObjectTO,
+            final ConnObject connObjectTO,
             final boolean notUser) {
 
         StatusBean statusBean = new StatusBean(anyTO, resource);
@@ -62,7 +62,7 @@ public final class StatusUtils implements Serializable {
     public static StatusBean getStatusBean(
             final RealmTO realmTO,
             final String resource,
-            final ConnObjectTO connObjectTO) {
+            final ConnObject connObjectTO) {
 
         StatusBean statusBean = new StatusBean(realmTO, resource);
 
@@ -77,14 +77,14 @@ public final class StatusUtils implements Serializable {
         return statusBean;
     }
 
-    public static Boolean isEnabled(final ConnObjectTO objectTO) {
+    public static Boolean isEnabled(final ConnObject objectTO) {
         Optional<Attr> status = objectTO.getAttr(ConnIdSpecialName.ENABLE);
         return status.isPresent() && status.get().getValues() != null && !status.get().getValues().isEmpty()
                 ? Boolean.valueOf(status.get().getValues().get(0))
                 : Boolean.FALSE;
     }
 
-    private static String getConnObjectLink(final ConnObjectTO objectTO) {
+    private static String getConnObjectLink(final ConnObject objectTO) {
         Optional<Attr> name = Optional.ofNullable(objectTO).map(to -> to.getAttr(ConnIdSpecialName.NAME)).orElse(null);
         return name != null && name.isPresent() && name.get().getValues() != null && !name.get().getValues().isEmpty()
                 ? name.get().getValues().get(0)
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoStatusProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoStatusProvider.java
index 93deafa274..dca6c753cb 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoStatusProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoStatusProvider.java
@@ -28,21 +28,21 @@ import org.apache.syncope.client.console.panels.ListViewPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.ui.commons.status.ConnObjectWrapper;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 
 public class IdRepoStatusProvider implements StatusProvider {
 
     private static final long serialVersionUID = -7948190795547208134L;
 
     @Override
-    public Optional<Pair<ConnObjectTO, ConnObjectTO>> get(
+    public Optional<Pair<ConnObject, ConnObject>> get(
             final String anyTypeKey, final String connObjectKeyValue, final String resource) {
 
         return Optional.empty();
     }
 
     @Override
-    public List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(
+    public List<Triple<ConnObject, ConnObjectWrapper, String>> get(
             final AnyTO any, final Collection<String> resources) {
 
         return List.of();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
index 114419f89c..df6a9916da 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/StatusProvider.java
@@ -28,14 +28,14 @@ import org.apache.syncope.client.console.panels.ListViewPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.ui.commons.status.ConnObjectWrapper;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 
 public interface StatusProvider extends Serializable {
 
-    Optional<Pair<ConnObjectTO, ConnObjectTO>> get(
+    Optional<Pair<ConnObject, ConnObject>> get(
             String anyTypeKey, String connObjectKeyValue, String resource);
 
-    List<Triple<ConnObjectTO, ConnObjectWrapper, String>> get(AnyTO any, Collection<String> resources);
+    List<Triple<ConnObject, ConnObjectWrapper, String>> get(AnyTO any, Collection<String> resources);
 
     <T extends Serializable> void addConnObjectLink(
             ListViewPanel.Builder<T> builder, ActionLink<T> connObjectLink);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index c0f9af09e2..d286e7b455 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -47,7 +47,7 @@ import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.PageReference;
@@ -279,7 +279,7 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E extends AbstractAnyRe
                 ((ProvisioningResult<A>) result).getEntity(),
                 new ListModel<>(new ArrayList<>()),
                 ((ProvisioningResult<A>) result).getPropagationStatuses().stream().map(status -> {
-                    ConnObjectTO before = status.getBeforeObj();
+                    ConnObject before = status.getBeforeObj();
                     ConnObjectWrapper afterObjWrapper = new ConnObjectWrapper(
                             ((ProvisioningResult<A>) result).getEntity(),
                             status.getResource(),
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index d99ed22241..7e1ad12c4e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -39,7 +39,7 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.status.StatusUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RealmTO;
@@ -162,7 +162,7 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
             @Override
             protected Component getValueComponent(final String key, final PropagationStatus bean) {
                 if ("afterObj".equalsIgnoreCase(key)) {
-                    ConnObjectTO afterObj = bean.getAfterObj();
+                    ConnObject afterObj = bean.getAfterObj();
                     String remoteId = afterObj == null
                             || afterObj.getAttrs().isEmpty()
                             || afterObj.getAttr(ConnIdSpecialName.NAME).isEmpty()
@@ -249,7 +249,7 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
         }
 
         @Override
-        protected final Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs() {
+        protected final Pair<ConnObject, ConnObject> getConnObjectTOs() {
             return Pair.of(bean.getBeforeObj(), bean.getAfterObj());
         }
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RemoteObjectPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RemoteObjectPanel.java
index 6c4231d967..11a88f131e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RemoteObjectPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RemoteObjectPanel.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.client.console.panels;
 
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 
 public abstract class RemoteObjectPanel extends MultilevelPanel.SecondLevel {
 
@@ -27,5 +27,5 @@ public abstract class RemoteObjectPanel extends MultilevelPanel.SecondLevel {
 
     protected static final String REMOTE_OBJECT_PANEL_ID = "remoteObject";
 
-    protected abstract Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs();
+    protected abstract Pair<ConnObject, ConnObject> getConnObjectTOs();
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ConnObjectAttrColumn.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ConnObjectAttrColumn.java
index 0e00d6c1c4..46bb9aab66 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ConnObjectAttrColumn.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ConnObjectAttrColumn.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.wicket.extensions.markup.html.repeater
 import java.util.List;
 import java.util.Optional;
 import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
@@ -30,7 +30,7 @@ import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.ResourceModel;
 
-public class ConnObjectAttrColumn extends AbstractColumn<ConnObjectTO, String> {
+public class ConnObjectAttrColumn extends AbstractColumn<ConnObject, String> {
 
     private static final long serialVersionUID = 2624734332447371372L;
 
@@ -45,9 +45,9 @@ public class ConnObjectAttrColumn extends AbstractColumn<ConnObjectTO, String> {
 
     @Override
     public void populateItem(
-            final Item<ICellPopulator<ConnObjectTO>> cellItem,
+            final Item<ICellPopulator<ConnObject>> cellItem,
             final String componentId,
-            final IModel<ConnObjectTO> rowModel) {
+            final IModel<ConnObject> rowModel) {
 
         Optional<Attr> attr = rowModel.getObject().getAttr(name);
         List<String> values = attr.map(Attr::getValues).orElse(null);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
index 65d34ae704..3f74823941 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/ItemTransformerWidget.java
@@ -22,7 +22,7 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
 import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType;
 import java.util.List;
 import org.apache.syncope.client.console.wizards.mapping.ItemTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.link.AbstractLink;
@@ -33,13 +33,13 @@ public class ItemTransformerWidget extends AlertWidget<String> {
 
     private static final long serialVersionUID = 7667120094526529934L;
 
-    private final ItemTO item;
+    private final Item item;
 
     private final ItemTransformersTogglePanel transformers;
 
     public ItemTransformerWidget(
             final String id,
-            final ItemTO item,
+            final Item item,
             final ItemTransformersTogglePanel transformers) {
 
         super(id);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
index bb1303de86..64b809e679 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JEXLTransformerWidget.java
+++ b/client/idrepo/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.mapping.JEXLTransformersTogglePanel;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.markup.html.link.AbstractLink;
@@ -35,13 +35,13 @@ public class JEXLTransformerWidget extends AlertWidget<String> {
 
     private static final long serialVersionUID = 7667120094526529934L;
 
-    private final ItemTO item;
+    private final Item item;
 
     private final JEXLTransformersTogglePanel transformers;
 
     public JEXLTransformerWidget(
             final String id,
-            final ItemTO item,
+            final Item item,
             final JEXLTransformersTogglePanel transformers) {
 
         super(id);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
index e224c40aea..587da008c0 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/ConnObjectPanel.java
@@ -32,7 +32,7 @@ import org.apache.syncope.client.ui.commons.ConnIdSpecialName;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.wicket.Component;
 import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.markup.ComponentTag;
@@ -53,7 +53,7 @@ public class ConnObjectPanel extends Panel {
     public ConnObjectPanel(
             final String id,
             final Pair<IModel<?>, IModel<?>> titles,
-            final Pair<ConnObjectTO, ConnObjectTO> connObjectTOs,
+            final Pair<ConnObject, ConnObject> connObjectTOs,
             final boolean hideLeft) {
 
         super(id);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index 484acae375..56fe8d68a4 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -38,7 +38,7 @@ import org.apache.syncope.client.ui.commons.status.Status;
 import org.apache.syncope.client.ui.commons.status.StatusBean;
 import org.apache.syncope.client.ui.commons.status.StatusUtils;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.Component;
@@ -75,7 +75,7 @@ public class StatusPanel extends Panel {
             final String id,
             final T any,
             final IModel<List<StatusBean>> model,
-            final List<Triple<ConnObjectTO, ConnObjectWrapper, String>> connObjects,
+            final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects,
             final PageReference pageRef) {
 
         super(id);
@@ -85,7 +85,7 @@ public class StatusPanel extends Panel {
     protected void init(
             final AnyTO any,
             final IModel<List<StatusBean>> model,
-            final List<Triple<ConnObjectTO, ConnObjectWrapper, String>> connObjects,
+            final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects,
             final PageReference pageRef,
             final boolean enableConnObjectLink) {
 
@@ -158,7 +158,7 @@ public class StatusPanel extends Panel {
 
             @Override
             protected boolean statusCondition(final StatusBean bean) {
-                Pair<ConnObjectTO, ConnObjectTO> pair =
+                Pair<ConnObject, ConnObject> pair =
                         getConnObjectTOs(bean.getKey(), bean.getResource(), connObjects);
                 return pair != null && pair.getRight() != null;
             }
@@ -200,12 +200,12 @@ public class StatusPanel extends Panel {
         return initialStatusBeanMap;
     }
 
-    protected static Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs(
+    protected static Pair<ConnObject, ConnObject> getConnObjectTOs(
             final String anyKey,
             final String resource,
-            final List<Triple<ConnObjectTO, ConnObjectWrapper, String>> objects) {
+            final List<Triple<ConnObject, ConnObjectWrapper, String>> objects) {
 
-        for (Triple<ConnObjectTO, ConnObjectWrapper, String> object : objects) {
+        for (Triple<ConnObject, ConnObjectWrapper, String> object : objects) {
             if (anyKey.equals(object.getMiddle().getAny().getKey())
                     && resource.equalsIgnoreCase(object.getMiddle().getResource())) {
 
@@ -222,9 +222,9 @@ public class StatusPanel extends Panel {
 
         protected final StatusBean bean;
 
-        protected final List<Triple<ConnObjectTO, ConnObjectWrapper, String>> connObjects;
+        protected final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects;
 
-        RemoteAnyPanel(final StatusBean bean, final List<Triple<ConnObjectTO, ConnObjectWrapper, String>> connObjects) {
+        RemoteAnyPanel(final StatusBean bean, final List<Triple<ConnObject, ConnObjectWrapper, String>> connObjects) {
             this.bean = bean;
             this.connObjects = connObjects;
 
@@ -236,7 +236,7 @@ public class StatusPanel extends Panel {
         }
 
         @Override
-        protected final Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs() {
+        protected final Pair<ConnObject, ConnObject> getConnObjectTOs() {
             return StatusPanel.getConnObjectTOs(bean.getKey(), bean.getResource(), connObjects);
         }
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
index e0ae003e8b..5ddc00f345 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/AbstractMappingPanel.java
@@ -34,7 +34,7 @@ import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
@@ -76,7 +76,7 @@ public abstract class AbstractMappingPanel extends Panel {
     /**
      * All mappings.
      */
-    protected final ListView<ItemTO> mappings;
+    protected final ListView<Item> mappings;
 
     /**
      * Mapping container.
@@ -87,7 +87,7 @@ public abstract class AbstractMappingPanel extends Panel {
             final String id,
             final ItemTransformersTogglePanel itemTransformers,
             final JEXLTransformersTogglePanel jexlTransformers,
-            final IModel<List<ItemTO>> model,
+            final IModel<List<Item>> model,
             final boolean addMappingBtnVisible,
             final MappingPurpose defaultPurpose) {
 
@@ -181,8 +181,8 @@ public abstract class AbstractMappingPanel extends Panel {
             private static final long serialVersionUID = 4949588177564901031L;
 
             @Override
-            protected void populateItem(final ListItem<ItemTO> item) {
-                final ItemTO itemTO = item.getModelObject();
+            protected void populateItem(final ListItem<Item> item) {
+                final Item itemTO = item.getModelObject();
                 if (itemTO.getPurpose() == null) {
                     itemTO.setPurpose(defaultPurpose);
                 }
@@ -380,7 +380,7 @@ public abstract class AbstractMappingPanel extends Panel {
 
             @Override
             protected void onSubmit(final AjaxRequestTarget target) {
-                model.getObject().add(new ItemTO());
+                model.getObject().add(new Item());
                 target.add(AbstractMappingPanel.this);
             }
         };
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/ItemTransformersTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/ItemTransformersTogglePanel.java
index 7e3ca1e939..ac580f4bd0 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/ItemTransformersTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/ItemTransformersTogglePanel.java
@@ -27,7 +27,7 @@ import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.common.lib.to.EntityTO;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -43,7 +43,7 @@ public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
 
     private static final long serialVersionUID = -3195479265440591519L;
 
-    private ItemTO item;
+    private Item item;
 
     public ItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
         super(Constants.OUTER, "itemTransformersTogglePanel", pageRef);
@@ -110,7 +110,7 @@ public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
         });
     }
 
-    public ItemTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+    public ItemTransformersTogglePanel setItem(final AjaxRequestTarget target, final Item item) {
         this.item = item;
         setHeader(target, StringUtils.EMPTY);
         return this;
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/JEXLTransformersTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/JEXLTransformersTogglePanel.java
index 7841029263..8fde87d063 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/JEXLTransformersTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/mapping/JEXLTransformersTogglePanel.java
@@ -23,7 +23,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.panels.TogglePanel;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
@@ -70,7 +70,7 @@ public class JEXLTransformersTogglePanel extends TogglePanel<Serializable> {
         });
     }
 
-    public JEXLTransformersTogglePanel setItem(final AjaxRequestTarget target, final ItemTO item) {
+    public JEXLTransformersTogglePanel setItem(final AjaxRequestTarget target, final Item item) {
         this.propagationJEXLTransformer.setNewModel(new PropertyModel<>(item, "propagationJEXLTransformer"));
         this.pullJEXLTransformer.setNewModel(new PropertyModel<>(item, "pullJEXLTransformer"));
         setHeader(target, StringUtils.EMPTY);
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyItemTransformer.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyItemTransformer.groovy
index 971b5584ba..e1eceda892 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyItemTransformer.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyItemTransformer.groovy
@@ -20,10 +20,10 @@ import groovy.transform.CompileStatic
 import java.util.List;
 import org.apache.commons.lang3.tuple.Pair
 import org.apache.syncope.common.lib.to.EntityTO
+import org.apache.syncope.common.lib.to.Item
 import org.apache.syncope.common.lib.types.AttrSchemaType
-import org.apache.syncope.core.persistence.api.entity.Entity
+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.Item
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer
 
 @CompileStatic
@@ -32,7 +32,7 @@ class MyItemTransformer implements ItemTransformer {
   @Override
   Pair<AttrSchemaType, List<PlainAttrValue>> beforePropagation(
     Item item,
-    Entity entity,
+    Any<?> any,
     AttrSchemaType schemaType,
     List<PlainAttrValue> values) {
 
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
index abdb3a4c1d..f92be605ec 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyLogicActions.groovy
@@ -17,9 +17,10 @@
  * under the License.
  */
 import groovy.transform.CompileStatic
-import org.apache.syncope.common.lib.request.AnyCR;
-import org.apache.syncope.common.lib.request.AnyUR;
-import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.request.AnyCR
+import org.apache.syncope.common.lib.request.AnyUR
+import org.apache.syncope.common.lib.to.AnyTO
+import org.apache.syncope.common.lib.to.PropagationStatus
 import org.apache.syncope.core.provisioning.api.LogicActions
 
 @CompileStatic
@@ -31,7 +32,7 @@ class MyLogicActions implements LogicActions {
   }
 
   @Override
-  <A extends AnyTO> A afterCreate(A input) {
+  <A extends AnyTO> A afterCreate(A input, List<PropagationStatus> statuses) {
     return input;
   }
 
@@ -41,7 +42,7 @@ class MyLogicActions implements LogicActions {
   }
 
   @Override
-  <A extends AnyTO> A afterUpdate(A input) {
+  <A extends AnyTO> A afterUpdate(A input, List<PropagationStatus> statuses) {
     return input;
   }
 
@@ -51,7 +52,7 @@ class MyLogicActions implements LogicActions {
   }
 
   @Override
-  <A extends AnyTO> A afterDelete(A input) {
+  <A extends AnyTO> A afterDelete(A input, List<PropagationStatus> statuses) {
     return input;
   }
 }
\ No newline at end of file
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy
index 4ac88eb04b..6c83796acb 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy
@@ -20,8 +20,8 @@
 import groovy.transform.CompileStatic
 import java.util.Optional
 import java.util.Set
-import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit
-import org.apache.syncope.core.persistence.api.entity.resource.Provision
+import org.apache.syncope.common.lib.to.OrgUnit
+import org.apache.syncope.common.lib.to.Provision
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyProvisionSorter.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyProvisionSorter.groovy
index c59a91ce14..f9d9bb72c7 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyProvisionSorter.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyProvisionSorter.groovy
@@ -18,9 +18,8 @@
  * under the License.
  */
 import groovy.transform.CompileStatic
-import org.apache.syncope.core.persistence.api.ProvisionSorter
-import org.apache.syncope.core.persistence.api.entity.resource.Provision
-
+import org.apache.syncope.common.lib.to.Provision
+import org.apache.syncope.core.provisioning.api.ProvisionSorter
 
 @CompileStatic
 class MyProvisionSorter implements ProvisionSorter {
@@ -29,5 +28,4 @@ class MyProvisionSorter implements ProvisionSorter {
   int compare(Provision provision1, Provision provision2) {
     return 0;
   }
-  
-}
\ No newline at end of file
+}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy
index e11a478d46..c8ee0be506 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy
@@ -23,9 +23,9 @@ import org.apache.syncope.common.lib.request.AnyUR
 import org.apache.syncope.common.lib.to.LinkedAccountTO
 import org.apache.syncope.common.lib.to.RealmTO
 import org.apache.syncope.common.lib.to.EntityTO
+import org.apache.syncope.common.lib.to.OrgUnit
+import org.apache.syncope.common.lib.to.Provision
 import org.apache.syncope.common.lib.to.ProvisioningReport
-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.persistence.api.entity.task.ProvisioningTask
 import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningActions
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullCorrelationRule.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullCorrelationRule.groovy
index 383afc245a..c4e3a8faec 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullCorrelationRule.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullCorrelationRule.groovy
@@ -17,9 +17,9 @@
  * under the License.
  */
 import groovy.transform.CompileStatic
+import org.apache.syncope.common.lib.to.Provision
 import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond
-import org.apache.syncope.core.persistence.api.entity.resource.Provision
 import org.identityconnectors.framework.common.objects.SyncDelta
 
 @CompileStatic
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushCorrelationRule.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushCorrelationRule.groovy
index ad3951db2a..f2547726d9 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushCorrelationRule.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushCorrelationRule.groovy
@@ -17,16 +17,17 @@
  * under the License.
  */
 import groovy.transform.CompileStatic
+import org.apache.syncope.common.lib.to.Provision
 import org.apache.syncope.core.persistence.api.dao.PushCorrelationRule
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.identityconnectors.framework.common.objects.filter.Filter;
+import org.apache.syncope.core.persistence.api.entity.Any
+import org.apache.syncope.core.persistence.api.entity.ExternalResource
+import org.identityconnectors.framework.common.objects.filter.Filter
 
 @CompileStatic
 class MyPushCorrelationRule implements PushCorrelationRule {
 
   @Override
-  Filter getFilter(Any<?> any, Provision provision) {
+  Filter getFilter(Any<?> any, ExternalResource resource, Provision provision) {
     
   }
 }
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportlet.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportlet.groovy
index 2ffc16c73b..e449c3632b 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportlet.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportlet.groovy
@@ -19,6 +19,7 @@
 import groovy.transform.CompileStatic
 import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
 import org.apache.syncope.core.persistence.api.dao.Reportlet
+import org.xml.sax.ContentHandler
 import org.xml.sax.SAXException
 import java.util.concurrent.atomic.AtomicReference
 
@@ -27,5 +28,5 @@ class MyReportlet implements Reportlet {
   
   @Override
   void extract(ContentHandler handler, AtomicReference<String> status) throws SAXException {
-  }
+  }  
 }
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy
index 3356319b04..550ae91b70 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy
@@ -22,8 +22,19 @@ import org.quartz.JobExecutionContext
 import org.quartz.JobExecutionException
 
 @CompileStatic
-class MySchedTaskJobDelegate implements SchedTaskJobDelegate {
-	
+class MySchedTaskJobDelegate implements SchedTaskJobDelegate {	
+
+  String currentStatus() {
+    return "RUNNING"
+  }
+
+  void interrupt() {
+  }
+
+  boolean isInterrupted() {
+    return false
+  }
+
   @Override
   void execute(String taskKey, boolean dryRun, JobExecutionContext context) throws JobExecutionException {
    
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AttrRepoTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AttrRepoTO.java
index a10712a026..93cf989b50 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AttrRepoTO.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AttrRepoTO.java
@@ -38,7 +38,7 @@ public class AttrRepoTO implements EntityTO {
 
     private int order = 0;
 
-    private final List<ItemTO> items = new ArrayList<>();
+    private final List<Item> items = new ArrayList<>();
 
     private AttrRepoConf conf;
 
@@ -77,7 +77,7 @@ public class AttrRepoTO implements EntityTO {
         this.order = order;
     }
 
-    public List<ItemTO> getItems() {
+    public List<Item> getItems() {
         return items;
     }
 
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java
index fa7239f406..2888ac9f78 100644
--- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/AuthModuleTO.java
@@ -38,7 +38,7 @@ public class AuthModuleTO implements EntityTO {
 
     private int order = 0;
 
-    private final List<ItemTO> items = new ArrayList<>();
+    private final List<Item> items = new ArrayList<>();
 
     private AuthModuleConf conf;
 
@@ -77,7 +77,7 @@ public class AuthModuleTO implements EntityTO {
         this.order = order;
     }
 
-    public List<ItemTO> getItems() {
+    public List<Item> getItems() {
         return items;
     }
 
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnBundleTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdBundle.java
similarity index 98%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnBundleTO.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdBundle.java
index 0b0911bb22..1256ef824c 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnBundleTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdBundle.java
@@ -25,7 +25,7 @@ import java.util.List;
 import org.apache.syncope.common.lib.BaseBean;
 import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 
-public class ConnBundleTO implements BaseBean {
+public class ConnIdBundle implements BaseBean {
 
     private static final long serialVersionUID = 7215115961910138005L;
 
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClass.java
similarity index 97%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClass.java
index 93b4a4fec8..fe5695cb90 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClass.java
@@ -27,7 +27,7 @@ import org.apache.syncope.common.lib.BaseBean;
 /**
  * Metadata description of ConnId ObjectClass.
  */
-public class ConnIdObjectClassTO implements BaseBean {
+public class ConnIdObjectClass implements BaseBean {
 
     private static final long serialVersionUID = -3719658595689434648L;
 
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java
similarity index 60%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java
index c29246a84f..81bb31f7cb 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java
@@ -22,19 +22,16 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Optional;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 
-public class MappingTO implements ItemContainerTO {
+public class Mapping extends ItemContainer {
 
     private static final long serialVersionUID = 8447688036282611118L;
 
     private String connObjectLink;
 
-    private final List<ItemTO> items = new ArrayList<>();
-
-    private final List<ItemTO> linkingItems = new ArrayList<>();
+    private final List<Item> linkingItems = new ArrayList<>();
 
     public String getConnObjectLink() {
         return connObjectLink;
@@ -44,44 +41,9 @@ public class MappingTO implements ItemContainerTO {
         this.connObjectLink = connObjectLink;
     }
 
-    @Override
-    public ItemTO getConnObjectKeyItem() {
-        return getItems().stream().filter(ItemTO::isConnObjectKey).findFirst().orElse(null);
-    }
-
-    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
-        connObjectItem.setMandatoryCondition("true");
-        connObjectItem.setConnObjectKey(true);
-
-        return this.add(connObjectItem);
-    }
-
-    @Override
-    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
-        return Optional.ofNullable(connObjectKeyItem)
-                .map(this::addConnObjectKeyItem).orElseGet(() -> remove(getConnObjectKeyItem()));
-    }
-
-    @JacksonXmlElementWrapper(localName = "items")
-    @JacksonXmlProperty(localName = "item")
-    @Override
-    public List<ItemTO> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean add(final ItemTO item) {
-        return Optional.ofNullable(item)
-                .filter(itemTO -> this.items.contains(itemTO) || this.items.add(itemTO)).isPresent();
-    }
-
-    public boolean remove(final ItemTO item) {
-        return this.items.remove(item);
-    }
-
     @JacksonXmlElementWrapper(localName = "linkingItems")
     @JacksonXmlProperty(localName = "linkingItem")
-    public List<ItemTO> getLinkingItems() {
+    public List<Item> getLinkingItems() {
         return linkingItems;
     }
 
@@ -96,10 +58,10 @@ public class MappingTO implements ItemContainerTO {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        MappingTO other = (MappingTO) obj;
+        Mapping other = (Mapping) obj;
         return new EqualsBuilder().
+                appendSuper(super.equals(obj)).
                 append(connObjectLink, other.connObjectLink).
-                append(items, other.items).
                 append(linkingItems, other.linkingItems).
                 build();
     }
@@ -107,8 +69,8 @@ public class MappingTO implements ItemContainerTO {
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
+                appendSuper(super.hashCode()).
                 append(connObjectLink).
-                append(items).
                 append(linkingItems).
                 build();
     }
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnit.java
similarity index 60%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnit.java
index 29cf761660..d0178830d7 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnitTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/OrgUnit.java
@@ -18,39 +18,20 @@
  */
 package org.apache.syncope.common.lib.to;
 
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 
-public class OrgUnitTO implements EntityTO, ItemContainerTO {
+public class OrgUnit extends ItemContainer {
 
     private static final long serialVersionUID = -1868877794174953177L;
 
-    private String key;
-
     private String objectClass;
 
-    private String syncToken;
-
-    private boolean ignoreCaseMatch;
-
     private String connObjectLink;
 
-    private final List<ItemTO> items = new ArrayList<>();
-
-    @Override
-    public String getKey() {
-        return key;
-    }
+    private String syncToken;
 
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
+    private boolean ignoreCaseMatch;
 
     public String getObjectClass() {
         return objectClass;
@@ -60,22 +41,6 @@ public class OrgUnitTO implements EntityTO, ItemContainerTO {
         this.objectClass = objectClass;
     }
 
-    public String getSyncToken() {
-        return syncToken;
-    }
-
-    public void setSyncToken(final String syncToken) {
-        this.syncToken = syncToken;
-    }
-
-    public boolean isIgnoreCaseMatch() {
-        return ignoreCaseMatch;
-    }
-
-    public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) {
-        this.ignoreCaseMatch = ignoreCaseMatch;
-    }
-
     public String getConnObjectLink() {
         return connObjectLink;
     }
@@ -84,39 +49,20 @@ public class OrgUnitTO implements EntityTO, ItemContainerTO {
         this.connObjectLink = connObjectLink;
     }
 
-    @Override
-    public ItemTO getConnObjectKeyItem() {
-        return getItems().stream().filter(ItemTO::isConnObjectKey).findFirst().orElse(null);
-    }
-
-    protected boolean addConnObjectKeyItem(final ItemTO connObjectItem) {
-        connObjectItem.setMandatoryCondition("true");
-        connObjectItem.setConnObjectKey(true);
-
-        return this.add(connObjectItem);
-    }
-
-    @Override
-    public boolean setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
-        return Optional.ofNullable(connObjectKeyItem)
-                .map(this::addConnObjectKeyItem).orElseGet(() -> remove(getConnObjectKeyItem()));
+    public String getSyncToken() {
+        return syncToken;
     }
 
-    @JacksonXmlElementWrapper(localName = "items")
-    @JacksonXmlProperty(localName = "item")
-    @Override
-    public List<ItemTO> getItems() {
-        return items;
+    public void setSyncToken(final String syncToken) {
+        this.syncToken = syncToken;
     }
 
-    @Override
-    public boolean add(final ItemTO item) {
-        return Optional.ofNullable(item)
-                .filter(itemTO -> this.items.contains(itemTO) || this.items.add(itemTO)).isPresent();
+    public boolean isIgnoreCaseMatch() {
+        return ignoreCaseMatch;
     }
 
-    public boolean remove(final ItemTO item) {
-        return this.items.remove(item);
+    public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) {
+        this.ignoreCaseMatch = ignoreCaseMatch;
     }
 
     @Override
@@ -130,26 +76,24 @@ public class OrgUnitTO implements EntityTO, ItemContainerTO {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        OrgUnitTO other = (OrgUnitTO) obj;
+        OrgUnit other = (OrgUnit) obj;
         return new EqualsBuilder().
+                appendSuper(super.equals(obj)).
                 append(ignoreCaseMatch, other.ignoreCaseMatch).
-                append(key, other.key).
                 append(objectClass, other.objectClass).
-                append(syncToken, other.syncToken).
                 append(connObjectLink, other.connObjectLink).
-                append(items, other.items).
+                append(syncToken, other.syncToken).
                 build();
     }
 
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
-                append(key).
+                appendSuper(super.hashCode()).
                 append(objectClass).
+                append(connObjectLink).
                 append(syncToken).
                 append(ignoreCaseMatch).
-                append(connObjectLink).
-                append(items).
                 build();
     }
 }
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectTOResult.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectResult.java
similarity index 95%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectTOResult.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectResult.java
index 57e2d1f101..8b61a8d508 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectTOResult.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/PagedConnObjectResult.java
@@ -27,13 +27,13 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.syncope.common.lib.BaseBean;
 
-public class PagedConnObjectTOResult implements BaseBean {
+public class PagedConnObjectResult implements BaseBean {
 
     private static final long serialVersionUID = -2832908019064402976L;
 
     private URI next;
 
-    private final List<ConnObjectTO> result = new ArrayList<>();
+    private final List<ConnObject> result = new ArrayList<>();
 
     private String pagedResultsCookie;
 
@@ -109,7 +109,7 @@ public class PagedConnObjectTOResult implements BaseBean {
 
     @JacksonXmlElementWrapper(localName = "result")
     @JacksonXmlProperty(localName = "item")
-    public List<ConnObjectTO> getResult() {
+    public List<ConnObject> getResult() {
         return result;
     }
 
@@ -135,7 +135,7 @@ public class PagedConnObjectTOResult implements BaseBean {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final PagedConnObjectTOResult other = (PagedConnObjectTOResult) obj;
+        final PagedConnObjectResult other = (PagedConnObjectResult) obj;
         return new EqualsBuilder().
                 append(next, other.next).
                 append(result, other.result).
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java
similarity index 89%
rename from common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
rename to common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java
index fb1190ec3f..9e82deaf77 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java
@@ -20,17 +20,16 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 
-public class ProvisionTO implements EntityTO {
+public class Provision implements Serializable {
 
     private static final long serialVersionUID = 8298910216218007927L;
 
-    private String key;
-
     private String anyType;
 
     private String objectClass;
@@ -43,20 +42,10 @@ public class ProvisionTO implements EntityTO {
 
     private String uidOnCreate;
 
-    private MappingTO mapping;
+    private Mapping mapping;
 
     private final List<String> virSchemas = new ArrayList<>();
 
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
     public String getAnyType() {
         return anyType;
     }
@@ -103,11 +92,11 @@ public class ProvisionTO implements EntityTO {
         this.uidOnCreate = uidOnCreate;
     }
 
-    public MappingTO getMapping() {
+    public Mapping getMapping() {
         return mapping;
     }
 
-    public void setMapping(final MappingTO mapping) {
+    public void setMapping(final Mapping mapping) {
         this.mapping = mapping;
     }
 
@@ -128,10 +117,9 @@ public class ProvisionTO implements EntityTO {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        ProvisionTO other = (ProvisionTO) obj;
+        Provision other = (Provision) obj;
         return new EqualsBuilder().
                 append(ignoreCaseMatch, other.ignoreCaseMatch).
-                append(key, other.key).
                 append(anyType, other.anyType).
                 append(objectClass, other.objectClass).
                 append(auxClasses, other.auxClasses).
@@ -145,7 +133,6 @@ public class ProvisionTO implements EntityTO {
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
-                append(key).
                 append(anyType).
                 append(objectClass).
                 append(auxClasses).
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ReconStatus.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ReconStatus.java
index eb4bd15045..de12932255 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ReconStatus.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ReconStatus.java
@@ -38,9 +38,9 @@ public class ReconStatus implements BaseBean {
 
     private MatchType matchType;
 
-    private ConnObjectTO onSyncope;
+    private ConnObject onSyncope;
 
-    private ConnObjectTO onResource;
+    private ConnObject onResource;
 
     @Schema(accessMode = Schema.AccessMode.READ_ONLY)
     public AnyTypeKind getAnyTypeKind() {
@@ -79,20 +79,20 @@ public class ReconStatus implements BaseBean {
     }
 
     @Schema(accessMode = Schema.AccessMode.READ_ONLY)
-    public ConnObjectTO getOnSyncope() {
+    public ConnObject getOnSyncope() {
         return onSyncope;
     }
 
-    public void setOnSyncope(final ConnObjectTO onSyncope) {
+    public void setOnSyncope(final ConnObject onSyncope) {
         this.onSyncope = onSyncope;
     }
 
     @Schema(accessMode = Schema.AccessMode.READ_ONLY)
-    public ConnObjectTO getOnResource() {
+    public ConnObject getOnResource() {
         return onResource;
     }
 
-    public void setOnResource(final ConnObjectTO onResource) {
+    public void setOnResource(final ConnObject onResource) {
         this.onResource = onResource;
     }
 }
diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index 59233a34ee..9cfd0df430 100644
--- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -47,9 +47,9 @@ public class ResourceTO implements EntityTO {
      */
     private String connectorDisplayName;
 
-    private final List<ProvisionTO> provisions = new ArrayList<>();
+    private final List<Provision> provisions = new ArrayList<>();
 
-    private OrgUnitTO orgUnit;
+    private OrgUnit orgUnit;
 
     private Integer propagationPriority;
 
@@ -229,21 +229,21 @@ public class ResourceTO implements EntityTO {
     }
 
     @JsonIgnore
-    public Optional<ProvisionTO> getProvision(final String anyType) {
+    public Optional<Provision> getProvision(final String anyType) {
         return provisions.stream().filter(
                 provision -> anyType != null && anyType.equals(provision.getAnyType())).
                 findFirst();
     }
 
-    public List<ProvisionTO> getProvisions() {
+    public List<Provision> getProvisions() {
         return provisions;
     }
 
-    public OrgUnitTO getOrgUnit() {
+    public OrgUnit getOrgUnit() {
         return orgUnit;
     }
 
-    public void setOrgUnit(final OrgUnitTO orgUnit) {
+    public void setOrgUnit(final OrgUnit orgUnit) {
         this.orgUnit = orgUnit;
     }
 
diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index a301e89ded..21ff1101e8 100644
--- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -42,8 +42,8 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
+import org.apache.syncope.common.lib.to.ConnIdObjectClass;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
@@ -66,7 +66,7 @@ public interface ConnectorService extends JAXRSService {
     @GET
     @Path("bundles")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    List<ConnBundleTO> getBundles(@QueryParam("lang") String lang);
+    List<ConnIdBundle> getBundles(@QueryParam("lang") String lang);
 
     /**
      * Builds the list of ConnId object classes information for the connector bundle matching the given connector
@@ -84,7 +84,7 @@ public interface ConnectorService extends JAXRSService {
     @Path("{key}/supportedObjectClasses")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
     @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    List<ConnIdObjectClassTO> buildObjectClassInfo(
+    List<ConnIdObjectClass> buildObjectClassInfo(
             @NotNull ConnInstanceTO connInstanceTO,
             @QueryParam("includeSpecial") @DefaultValue("false") boolean includeSpecial);
 
diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
index 54e9df9bb9..e0db20a1a3 100644
--- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
+++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
@@ -42,8 +42,8 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.to.PagedConnObjectResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.ConnObjectTOQuery;
@@ -94,7 +94,7 @@ public interface ResourceService extends JAXRSService {
     @GET
     @Path("{key}/{anyTypeKey}/{value}")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    ConnObjectTO readConnObject(
+    ConnObject readConnObject(
             @NotNull @PathParam("key") String key,
             @NotNull @PathParam("anyTypeKey") String anyTypeKey,
             @NotNull @PathParam("value") String value);
@@ -111,7 +111,7 @@ public interface ResourceService extends JAXRSService {
     @GET
     @Path("{key}/{anyTypeKey}")
     @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
-    PagedConnObjectTOResult searchConnObjects(
+    PagedConnObjectResult searchConnObjects(
             @NotNull @PathParam("key") String key,
             @NotNull @PathParam("anyTypeKey") String anyTypeKey,
             @BeanParam ConnObjectTOQuery connObjectTOQuery);
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObject.java
similarity index 96%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObject.java
index 921364d11e..c26b85937b 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObject.java
@@ -29,7 +29,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.BaseBean;
 
-public class ConnObjectTO implements BaseBean {
+public class ConnObject implements BaseBean {
 
     private static final long serialVersionUID = 5139554911265442497L;
 
@@ -75,7 +75,7 @@ public class ConnObjectTO implements BaseBean {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final ConnObjectTO other = (ConnObjectTO) obj;
+        final ConnObject other = (ConnObject) obj;
         return new EqualsBuilder().
                 append(fiql, other.fiql).
                 append(attrs, other.attrs).
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/Item.java
similarity index 94%
rename from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
rename to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/Item.java
index 2bd53cae72..1cd85207c9 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/Item.java
@@ -20,18 +20,17 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 
-public class ItemTO implements EntityTO {
+public class Item implements Serializable {
 
     private static final long serialVersionUID = 2983498836767176862L;
 
-    private String key;
-
     /**
      * Attribute schema to be mapped. Consider other we can associate tha same attribute schema more than once, with
      * different aliases, to different resource attributes.
@@ -91,16 +90,6 @@ public class ItemTO implements EntityTO {
         this.extAttrName = extAttrName;
     }
 
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
     public String getMandatoryCondition() {
         return mandatoryCondition;
     }
@@ -166,11 +155,10 @@ public class ItemTO implements EntityTO {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        ItemTO other = (ItemTO) obj;
+        Item other = (Item) obj;
         return new EqualsBuilder().
                 append(connObjectKey, other.connObjectKey).
                 append(password, other.password).
-                append(key, other.key).
                 append(intAttrName, other.intAttrName).
                 append(extAttrName, other.extAttrName).
                 append(mandatoryCondition, other.mandatoryCondition).
@@ -184,7 +172,6 @@ public class ItemTO implements EntityTO {
     @Override
     public int hashCode() {
         return new HashCodeBuilder().
-                append(key).
                 append(intAttrName).
                 append(extAttrName).
                 append(connObjectKey).
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainer.java
similarity index 55%
rename from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
rename to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainer.java
index 921364d11e..40d7a776f6 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainer.java
@@ -21,47 +21,46 @@ package org.apache.syncope.common.lib.to;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.syncope.common.lib.Attr;
-import org.apache.syncope.common.lib.BaseBean;
 
-public class ConnObjectTO implements BaseBean {
+public abstract class ItemContainer implements Serializable {
 
-    private static final long serialVersionUID = 5139554911265442497L;
+    private static final long serialVersionUID = 3637981417797873343L;
 
-    private String fiql;
+    private final List<Item> items = new ArrayList<>();
 
-    private final Set<Attr> attrs = new TreeSet<>();
-
-    public String getFiql() {
-        return fiql;
+    @JsonIgnore
+    public Optional<Item> getConnObjectKeyItem() {
+        return getItems().stream().filter(Item::isConnObjectKey).findFirst();
     }
 
-    public void setFiql(final String fiql) {
-        this.fiql = fiql;
+    protected boolean addConnObjectKeyItem(final Item connObjectItem) {
+        connObjectItem.setMandatoryCondition("true");
+        connObjectItem.setConnObjectKey(true);
+
+        return add(connObjectItem);
     }
 
-    @JacksonXmlElementWrapper(localName = "attrs")
-    @JacksonXmlProperty(localName = "attr")
-    public Set<Attr> getAttrs() {
-        return attrs;
+    public boolean setConnObjectKeyItem(final Item connObjectKeyItem) {
+        return Optional.ofNullable(connObjectKeyItem).
+                map(this::addConnObjectKeyItem).
+                orElseGet(() -> getConnObjectKeyItem().map(items::remove).orElse(false));
     }
 
-    @JsonIgnore
-    public Optional<Attr> getAttr(final String schema) {
-        return attrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst();
+    @JacksonXmlElementWrapper(localName = "items")
+    @JacksonXmlProperty(localName = "item")
+    public List<Item> getItems() {
+        return items;
     }
 
-    @Override
-    public int hashCode() {
-        return new HashCodeBuilder().
-                append(fiql).
-                append(attrs).
-                build();
+    public boolean add(final Item item) {
+        return Optional.ofNullable(item).
+                filter(itemTO -> items.contains(itemTO) || items.add(itemTO)).isPresent();
     }
 
     @Override
@@ -75,10 +74,16 @@ public class ConnObjectTO implements BaseBean {
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final ConnObjectTO other = (ConnObjectTO) obj;
+        final ItemContainer other = (ItemContainer) obj;
         return new EqualsBuilder().
-                append(fiql, other.fiql).
-                append(attrs, other.attrs).
+                append(items, other.items).
+                build();
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(items).
                 build();
     }
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
deleted file mode 100644
index a8b3ff3c21..0000000000
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/ItemContainerTO.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.to;
-
-import java.util.List;
-import org.apache.syncope.common.lib.BaseBean;
-
-public interface ItemContainerTO extends BaseBean {
-
-    ItemTO getConnObjectKeyItem();
-
-    boolean setConnObjectKeyItem(ItemTO connObjectKeyItem);
-
-    boolean add(ItemTO item);
-
-    List<ItemTO> getItems();
-}
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
index e41b4471df..14898b7626 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
@@ -33,12 +33,12 @@ public class PropagationStatus implements BaseBean {
     /**
      * Object before propagation.
      */
-    private ConnObjectTO beforeObj;
+    private ConnObject beforeObj;
 
     /**
      * Object after propagation.
      */
-    private ConnObjectTO afterObj;
+    private ConnObject afterObj;
 
     /**
      * Propagated resource name.
@@ -55,19 +55,19 @@ public class PropagationStatus implements BaseBean {
      */
     private String failureReason;
 
-    public ConnObjectTO getAfterObj() {
+    public ConnObject getAfterObj() {
         return afterObj;
     }
 
-    public void setAfterObj(final ConnObjectTO afterObj) {
+    public void setAfterObj(final ConnObject afterObj) {
         this.afterObj = afterObj;
     }
 
-    public ConnObjectTO getBeforeObj() {
+    public ConnObject getBeforeObj() {
         return beforeObj;
     }
 
-    public void setBeforeObj(final ConnObjectTO beforeObj) {
+    public void setBeforeObj(final ConnObject beforeObj) {
         this.beforeObj = beforeObj;
     }
 
diff --git a/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java b/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java
index 1675726280..e804951bf2 100644
--- a/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java
+++ b/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java
@@ -34,7 +34,7 @@ import org.apache.syncope.common.lib.request.PasswordPatch;
 import org.apache.syncope.common.lib.request.StringPatchItem;
 import org.apache.syncope.common.lib.request.StringReplacePatchItem;
 import org.apache.syncope.common.lib.request.UserUR;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -144,7 +144,7 @@ public abstract class SerializationTest {
 
         PropagationStatus status = new PropagationStatus();
         status.setFailureReason("failed");
-        status.setBeforeObj(new ConnObjectTO());
+        status.setBeforeObj(new ConnObject());
         original.getPropagationStatuses().add(status);
 
         StringWriter writer = new StringWriter();
diff --git a/core/idm/logic/pom.xml b/core/idm/logic/pom.xml
index 9ea2854f26..cc9e33d9e3 100644
--- a/core/idm/logic/pom.xml
+++ b/core/idm/logic/pom.xml
@@ -81,6 +81,11 @@ under the License.
       <artifactId>spring-test</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter</artifactId>
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index a4606fbe74..03c22af783 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -29,8 +29,8 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
+import org.apache.syncope.common.lib.to.ConnIdObjectClass;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
@@ -40,7 +40,7 @@ import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
@@ -178,17 +178,17 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
 
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_READ + "')")
     @Transactional(readOnly = true)
-    public List<ConnBundleTO> getBundles(final String lang) {
+    public List<ConnIdBundle> getBundles(final String lang) {
         if (StringUtils.isBlank(lang)) {
             CurrentLocale.set(Locale.ENGLISH);
         } else {
             CurrentLocale.set(new Locale(lang));
         }
 
-        List<ConnBundleTO> connectorBundleTOs = new ArrayList<>();
+        List<ConnIdBundle> connectorBundleTOs = new ArrayList<>();
         connIdBundleManager.getConnInfoManagers().forEach((uri, cim) -> connectorBundleTOs.addAll(
                 cim.getConnectorInfos().stream().map(bundle -> {
-                    ConnBundleTO connBundleTO = new ConnBundleTO();
+                    ConnIdBundle connBundleTO = new ConnIdBundle();
                     connBundleTO.setDisplayName(bundle.getConnectorDisplayName());
 
                     connBundleTO.setLocation(uri.toString());
@@ -211,7 +211,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
 
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_READ + "')")
 
-    public List<ConnIdObjectClassTO> buildObjectClassInfo(
+    public List<ConnIdObjectClass> buildObjectClassInfo(
             final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
 
         ConnInstanceTO actual = connInstanceTO;
@@ -225,7 +225,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
                 getObjectClassInfo();
 
         return objectClassInfo.stream().map(info -> {
-            ConnIdObjectClassTO connIdObjectClassTO = new ConnIdObjectClassTO();
+            ConnIdObjectClass connIdObjectClassTO = new ConnIdObjectClass();
             connIdObjectClassTO.setType(info.getType());
             connIdObjectClassTO.setAuxiliary(info.isAuxiliary());
             connIdObjectClassTO.setContainer(info.isContainer());
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
index 2168de9c1c..5223b589ac 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
@@ -29,11 +29,14 @@ import java.util.Set;
 import java.util.stream.Stream;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
 import org.apache.syncope.common.lib.to.EntityTO;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.ProvisioningReport;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
@@ -62,11 +65,9 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 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;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.MappingManager;
@@ -92,6 +93,7 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.OperationOptions;
 import org.identityconnectors.framework.common.objects.SearchResult;
 import org.identityconnectors.framework.common.objects.SyncDeltaBuilder;
@@ -163,7 +165,9 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         this.connectorManager = connectorManager;
     }
 
-    protected Provision getProvision(final String anyTypeKey, final String resourceKey) {
+    protected Triple<AnyType, ExternalResource, Provision> getProvision(
+            final String anyTypeKey, final String resourceKey) {
+
         AnyType anyType = anyTypeDAO.find(anyTypeKey);
         if (anyType == null) {
             throw new NotFoundException("AnyType '" + anyTypeKey + "'");
@@ -173,22 +177,22 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + resourceKey + "'");
         }
-        Provision provision = resource.getProvision(anyType).
+        Provision provision = resource.getProvision(anyType.getKey()).
                 orElseThrow(() -> new NotFoundException(
                 "Provision for " + anyType + " on Resource '" + resourceKey + "'"));
         if (provision.getMapping() == null) {
             throw new NotFoundException("Mapping for " + anyType + " on Resource '" + resourceKey + "'");
         }
 
-        return provision;
+        return Triple.of(anyType, resource, provision);
     }
 
-    protected ConnObjectTO getOnSyncope(
-            final MappingItem connObjectKeyItem,
+    protected ConnObject getOnSyncope(
+            final Item connObjectKeyItem,
             final String connObjectKeyValue,
             final Set<Attribute> attrs) {
 
-        ConnObjectTO connObjectTO = ConnObjectUtils.getConnObjectTO(null, attrs);
+        ConnObject connObjectTO = ConnObjectUtils.getConnObjectTO(null, attrs);
         connObjectTO.getAttrs().add(new Attr.Builder(connObjectKeyItem.getExtAttrName()).
                 value(connObjectKeyValue).build());
         connObjectTO.getAttrs().add(new Attr.Builder(Uid.NAME).
@@ -197,19 +201,20 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return connObjectTO;
     }
 
-    protected ConnObjectTO getOnSyncope(
+    protected ConnObject getOnSyncope(
             final Any<?> any,
-            final MappingItem connObjectKeyItem,
+            final Item connObjectKeyItem,
+            final ExternalResource resource,
             final Provision provision) {
 
         Pair<String, Set<Attribute>> prepared = mappingManager.prepareAttrsFromAny(
-                any, null, false, true, provision);
+                any, null, false, true, resource, provision);
         return getOnSyncope(connObjectKeyItem, prepared.getLeft(), prepared.getRight());
     }
 
-    protected ConnObjectTO getOnSyncope(
+    protected ConnObject getOnSyncope(
             final LinkedAccount account,
-            final MappingItem connObjectKeyItem,
+            final Item connObjectKeyItem,
             final Provision provision) {
 
         Set<Attribute> attrs = mappingManager.prepareAttrsFromLinkedAccount(
@@ -217,13 +222,13 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return getOnSyncope(connObjectKeyItem, account.getConnObjectKeyValue(), attrs);
     }
 
-    protected Any<?> getAny(final Provision provision, final String anyKey) {
-        AnyDAO<Any<?>> dao = anyUtilsFactory.getInstance(provision.getAnyType().getKind()).dao();
+    protected Any<?> getAny(final Provision provision, final AnyTypeKind anyTypeKind, final String anyKey) {
+        AnyDAO<Any<?>> dao = anyUtilsFactory.getInstance(anyTypeKind).dao();
         Any<?> any = SyncopeConstants.UUID_PATTERN.matcher(anyKey).matches()
                 ? dao.authFind(anyKey)
                 : dao.authFind(dao.findKey(anyKey));
         if (any == null) {
-            throw new NotFoundException(provision.getAnyType().getKey() + " '" + anyKey + "'");
+            throw new NotFoundException(provision.getAnyType() + " '" + anyKey + "'");
         }
         return any;
     }
@@ -235,27 +240,32 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final String anyKey,
             final Set<String> moreAttrsToGet) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
-        MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision).
+        Item connObjectKeyItem = MappingUtils.getConnObjectKeyItem(triple.getRight()).
                 orElseThrow(() -> new NotFoundException(
-                "ConnObjectKey for " + provision.getAnyType().getKey()
-                + " on resource '" + provision.getResource().getKey() + "'"));
+                "ConnObjectKey for " + triple.getLeft().getKey()
+                + " on resource '" + triple.getMiddle().getKey() + "'"));
 
-        Any<?> any = getAny(provision, anyKey);
+        Any<?> any = getAny(triple.getRight(), triple.getLeft().getKind(), anyKey);
 
         ReconStatus status = new ReconStatus();
         status.setMatchType(MatchType.ANY);
         status.setAnyTypeKind(any.getType().getKind());
         status.setAnyKey(any.getKey());
         status.setRealm(any.getRealm().getFullPath());
-        status.setOnSyncope(getOnSyncope(any, connObjectKeyItem, provision));
-
-        List<ConnectorObject> connObjs = outboundMatcher.match(connectorManager.getConnector(
-                provision.getResource()), any, provision, Optional.of(moreAttrsToGet.toArray(String[]::new)));
+        status.setOnSyncope(getOnSyncope(any, connObjectKeyItem, triple.getMiddle(), triple.getRight()));
+
+        List<ConnectorObject> connObjs = outboundMatcher.match(
+                connectorManager.getConnector(triple.getMiddle()),
+                any,
+                triple.getMiddle(),
+                triple.getRight(),
+                Optional.of(moreAttrsToGet.toArray(String[]::new)));
         if (!connObjs.isEmpty()) {
             status.setOnResource(ConnObjectUtils.getConnObjectTO(
-                    outboundMatcher.getFIQL(connObjs.get(0), provision), connObjs.get(0).getAttributes()));
+                    outboundMatcher.getFIQL(connObjs.get(0), triple.getMiddle(), triple.getRight()),
+                    connObjs.get(0).getAttributes()));
 
             if (connObjs.size() > 1) {
                 LOG.warn("Expected single match, found {}", connObjs);
@@ -268,21 +278,23 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
     }
 
     protected SyncDeltaBuilder syncDeltaBuilder(
+            final AnyType anyType,
+            final ExternalResource resource,
             final Provision provision,
             final Filter filter,
             final Set<String> moreAttrsToGet) {
 
-        Stream<MappingItem> mapItems = Stream.concat(
+        Stream<Item> mapItems = Stream.concat(
                 provision.getMapping().getItems().stream(),
-                virSchemaDAO.findByProvision(provision).stream().map(VirSchema::asLinkingMappingItem));
+                virSchemaDAO.find(resource.getKey(), anyType.getKey()).stream().map(VirSchema::asLinkingMappingItem));
         OperationOptions options = MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(String[]::new));
 
         SyncDeltaBuilder syncDeltaBuilder = new SyncDeltaBuilder().
                 setToken(new SyncToken("")).
                 setDeltaType(SyncDeltaType.CREATE_OR_UPDATE).
-                setObjectClass(provision.getObjectClass());
-        connectorManager.getConnector(provision.getResource()).
-                search(provision.getObjectClass(), filter, new SearchResultsHandler() {
+                setObjectClass(new ObjectClass(provision.getObjectClass()));
+        connectorManager.getConnector(resource).
+                search(syncDeltaBuilder.getObjectClass(), filter, new SearchResultsHandler() {
 
                     @Override
                     public boolean handle(final ConnectorObject connObj) {
@@ -306,39 +318,47 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final Filter filter,
             final Set<String> moreAttrsToGet) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
-        SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder(provision, filter, moreAttrsToGet);
+        SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder(
+                triple.getLeft(), triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet);
 
         ReconStatus status = new ReconStatus();
         if (syncDeltaBuilder.getObject() != null) {
-            MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision).
+            Item connObjectKeyItem = MappingUtils.getConnObjectKeyItem(triple.getRight()).
                     orElseThrow(() -> new NotFoundException(
-                    "ConnObjectKey for " + provision.getAnyType().getKey()
-                    + " on resource '" + provision.getResource().getKey() + "'"));
-
-            inboundMatcher.match(syncDeltaBuilder.build(), provision).stream().findFirst().ifPresent(match -> {
-                if (match.getAny() != null) {
-                    status.setMatchType(MatchType.ANY);
-                    status.setAnyTypeKind(match.getAny().getType().getKind());
-                    status.setAnyKey(match.getAny().getKey());
-                    status.setRealm(match.getAny().getRealm().getFullPath());
-                    status.setOnSyncope(getOnSyncope(match.getAny(), connObjectKeyItem, provision));
-                } else if (match.getLinkedAccount() != null) {
-                    status.setMatchType(MatchType.LINKED_ACCOUNT);
-                    status.setAnyTypeKind(AnyTypeKind.USER);
-                    status.setAnyKey(match.getLinkedAccount().getOwner().getKey());
-                    status.setRealm(match.getLinkedAccount().getOwner().getRealm().getFullPath());
-                    status.setOnSyncope(getOnSyncope(match.getLinkedAccount(), connObjectKeyItem, provision));
-                }
-            });
+                    "ConnObjectKey for " + triple.getLeft().getKey()
+                    + " on resource '" + triple.getMiddle().getKey() + "'"));
+
+            inboundMatcher.match(
+                    syncDeltaBuilder.build(), triple.getMiddle(), triple.getRight(), triple.getLeft().getKind()).
+                    stream().findFirst().ifPresent(match -> {
+
+                        if (match.getAny() != null) {
+                            status.setMatchType(MatchType.ANY);
+                            status.setAnyTypeKind(match.getAny().getType().getKind());
+                            status.setAnyKey(match.getAny().getKey());
+                            status.setRealm(match.getAny().getRealm().getFullPath());
+                            status.setOnSyncope(getOnSyncope(
+                                    match.getAny(), connObjectKeyItem, triple.getMiddle(), triple.getRight()));
+                        } else if (match.getLinkedAccount() != null) {
+                            status.setMatchType(MatchType.LINKED_ACCOUNT);
+                            status.setAnyTypeKind(AnyTypeKind.USER);
+                            status.setAnyKey(match.getLinkedAccount().getOwner().getKey());
+                            status.setRealm(match.getLinkedAccount().getOwner().getRealm().getFullPath());
+                            status.setOnSyncope(getOnSyncope(
+                                    match.getLinkedAccount(), connObjectKeyItem, triple.getRight()));
+                        }
+                    });
 
             status.setOnResource(ConnObjectUtils.getConnObjectTO(
-                    outboundMatcher.getFIQL(syncDeltaBuilder.getObject(), provision),
+                    outboundMatcher.getFIQL(syncDeltaBuilder.getObject(), triple.getMiddle(), triple.getRight()),
                     syncDeltaBuilder.getObject().getAttributes()));
 
             if (status.getMatchType() == MatchType.ANY && StringUtils.isNotBlank(status.getAnyKey())) {
-                virAttrHandler.setValues(getAny(provision, status.getAnyKey()), syncDeltaBuilder.getObject());
+                virAttrHandler.setValues(
+                        getAny(triple.getRight(), triple.getLeft().getKind(), status.getAnyKey()),
+                        syncDeltaBuilder.getObject());
             }
         }
 
@@ -357,15 +377,16 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final String anyKey,
             final PushTaskTO pushTask) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Reconciliation);
         List<ProvisioningReport> results = new ArrayList<>();
         try {
             results.addAll(singlePushExecutor().push(
-                    provision,
-                    connectorManager.getConnector(provision.getResource()),
-                    getAny(provision, anyKey),
+                    triple.getMiddle(),
+                    triple.getRight(),
+                    connectorManager.getConnector(triple.getMiddle()),
+                    getAny(triple.getRight(), triple.getLeft().getKind(), anyKey),
                     pushTask,
                     AuthContextUtils.getWho()));
             if (!results.isEmpty() && results.get(0).getStatus() == ProvisioningReport.Status.FAILURE) {
@@ -390,43 +411,51 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final Set<String> moreAttrsToGet,
             final PushTaskTO pushTask) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
-        SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder(provision, filter, moreAttrsToGet);
+        SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder(
+                triple.getLeft(), triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet);
 
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Reconciliation);
         List<ProvisioningReport> results = new ArrayList<>();
 
         if (syncDeltaBuilder.getObject() != null) {
-            inboundMatcher.match(syncDeltaBuilder.build(), provision).stream().findFirst().ifPresent(match -> {
-                try {
-                    if (match.getMatchTarget() == MatchType.ANY) {
-                        results.addAll(singlePushExecutor().push(
-                                provision,
-                                connectorManager.getConnector(provision.getResource()),
-                                match.getAny(),
-                                pushTask,
-                                AuthContextUtils.getWho()));
-                        if (!results.isEmpty() && results.get(0).getStatus() == ProvisioningReport.Status.FAILURE) {
-                            sce.getElements().add(results.get(0).getMessage());
+            inboundMatcher.match(
+                    syncDeltaBuilder.build(), triple.getMiddle(), triple.getRight(), triple.getLeft().getKind()).
+                    stream().findFirst().ifPresent(match -> {
+
+                        try {
+                            if (match.getMatchTarget() == MatchType.ANY) {
+                                results.addAll(singlePushExecutor().push(
+                                        triple.getMiddle(),
+                                        triple.getRight(),
+                                        connectorManager.getConnector(triple.getMiddle()),
+                                        match.getAny(),
+                                        pushTask,
+                                        AuthContextUtils.getWho()));
+                                if (!results.isEmpty()
+                                        && results.get(0).getStatus() == ProvisioningReport.Status.FAILURE) {
+
+                                    sce.getElements().add(results.get(0).getMessage());
+                                }
+                            } else {
+                                ProvisioningReport result = singlePushExecutor().push(
+                                        triple.getMiddle(),
+                                        triple.getRight(),
+                                        connectorManager.getConnector(triple.getMiddle()),
+                                        match.getLinkedAccount(),
+                                        pushTask,
+                                        AuthContextUtils.getWho());
+                                if (result.getStatus() == ProvisioningReport.Status.FAILURE) {
+                                    sce.getElements().add(result.getMessage());
+                                } else {
+                                    results.add(result);
+                                }
+                            }
+                        } catch (JobExecutionException e) {
+                            sce.getElements().add(e.getMessage());
                         }
-                    } else {
-                        ProvisioningReport result = singlePushExecutor().push(
-                                provision,
-                                connectorManager.getConnector(provision.getResource()),
-                                match.getLinkedAccount(),
-                                pushTask,
-                                AuthContextUtils.getWho());
-                        if (result.getStatus() == ProvisioningReport.Status.FAILURE) {
-                            sce.getElements().add(result.getMessage());
-                        } else {
-                            results.add(result);
-                        }
-                    }
-                } catch (JobExecutionException e) {
-                    sce.getElements().add(e.getMessage());
-                }
-            });
+                    });
         }
 
         if (!sce.isEmpty()) {
@@ -437,6 +466,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
     }
 
     protected List<ProvisioningReport> pull(
+            final ExternalResource resource,
             final Provision provision,
             final ReconFilterBuilder reconFilterBuilder,
             final Set<String> moreAttrsToGet,
@@ -454,8 +484,9 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
                             createBean(SinglePullJobDelegate.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
 
             results.addAll(executor.pull(
+                    resource,
                     provision,
-                    connectorManager.getConnector(provision.getResource()),
+                    connectorManager.getConnector(resource),
                     reconFilterBuilder,
                     moreAttrsToGet,
                     pullTask,
@@ -483,24 +514,26 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final Set<String> moreAttrsToGet,
             final PullTaskTO pullTask) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
-        Any<?> any = getAny(provision, anyKey);
-
-        if (provision.getMapping().getConnObjectKeyItem().isEmpty()) {
+        if (triple.getRight().getMapping().getConnObjectKeyItem().isEmpty()) {
             throw new NotFoundException(
-                    "ConnObjectKey cannot be determined for mapping " + provision.getMapping().getKey());
+                    "ConnObjectKey cannot be determined for mapping " + anyTypeKey);
         }
 
-        String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, provision).
+        Any<?> any = getAny(triple.getRight(), triple.getLeft().getKind(), anyKey);
+
+        String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, triple.getMiddle(), triple.getRight()).
                 orElseThrow(() -> new NotFoundException(
-                "ConnObjectKey for " + provision.getAnyType().getKey()
-                + " on resource '" + provision.getResource().getKey() + "'"));
+                "ConnObjectKey for " + triple.getLeft().getKey()
+                + " on resource '" + triple.getMiddle().getKey() + "'"));
 
         return pull(
-                provision,
+                triple.getMiddle(),
+                triple.getRight(),
                 new KeyValueReconFilterBuilder(
-                        provision.getMapping().getConnObjectKeyItem().get().getExtAttrName(), connObjectKeyValue),
+                        triple.getRight().getMapping().getConnObjectKeyItem().get().getExtAttrName(),
+                        connObjectKeyValue),
                 moreAttrsToGet,
                 pullTask);
     }
@@ -514,10 +547,11 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
             final Set<String> moreAttrsToGet,
             final PullTaskTO pullTask) {
 
-        Provision provision = getProvision(anyTypeKey, resourceKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, resourceKey);
 
         return pull(
-                provision,
+                triple.getMiddle(),
+                triple.getRight(),
                 new ConstantReconFilterBuilder(filter),
                 moreAttrsToGet,
                 pullTask);
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 3e264f6285..5407d59136 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -28,9 +28,12 @@ import java.util.stream.Stream;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
@@ -45,10 +48,8 @@ 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.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 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;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.MappingManager;
@@ -181,10 +182,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_UPDATE + "')")
     public void setLatestSyncToken(final String key, final String anyTypeKey) {
-        ExternalResource resource = resourceDAO.authFind(key);
-        if (resource == null) {
-            throw new NotFoundException("Resource '" + key + '\'');
-        }
+        ExternalResource resource = Optional.ofNullable(resourceDAO.authFind(key)).
+                orElseThrow(() -> new NotFoundException("Resource '" + key + '\''));
 
         Connector connector;
         try {
@@ -200,18 +199,19 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 throw new NotFoundException("Realm provision not enabled for Resource '" + key + '\'');
             }
 
-            resource.getOrgUnit().setSyncToken(connector.getLatestSyncToken(resource.getOrgUnit().getObjectClass()));
+            resource.getOrgUnit().setSyncToken(ConnObjectUtils.toString(
+                    connector.getLatestSyncToken(new ObjectClass(resource.getOrgUnit().getObjectClass()))));
         } else {
             AnyType anyType = anyTypeDAO.find(anyTypeKey);
             if (anyType == null) {
                 throw new NotFoundException("AnyType '" + anyTypeKey + '\'');
             }
-            Optional<? extends Provision> provision = resource.getProvision(anyType);
-            if (provision.isEmpty()) {
-                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + '\'');
-            }
+            Provision provision = resource.getProvision(anyType.getKey()).
+                    orElseThrow(() -> new NotFoundException(
+                    "Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + '\''));
 
-            provision.get().setSyncToken(connector.getLatestSyncToken(provision.get().getObjectClass()));
+            provision.setSyncToken(ConnObjectUtils.toString(
+                    connector.getLatestSyncToken(new ObjectClass(provision.getObjectClass()))));
         }
 
         Set<String> effectiveRealms = RealmUtils.getEffective(
@@ -239,12 +239,11 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             if (anyType == null) {
                 throw new NotFoundException("AnyType '" + anyTypeKey + '\'');
             }
-            Optional<? extends Provision> provision = resource.getProvision(anyType);
-            if (provision.isEmpty()) {
-                throw new NotFoundException("Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + '\'');
-            }
+            Provision provision = resource.getProvision(anyType.getKey()).
+                    orElseThrow(() -> new NotFoundException(
+                    "Provision for AnyType '" + anyTypeKey + "' in Resource '" + key + '\''));
 
-            provision.get().setSyncToken(null);
+            provision.setSyncToken(null);
         }
 
         Set<String> effectiveRealms = RealmUtils.getEffective(
@@ -291,20 +290,26 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         return resourceDAO.findAll().stream().map(binder::getResourceTO).collect(Collectors.toList());
     }
 
-    protected Provision getProvision(final String resourceKey, final String anyTypeKey) {
-        ExternalResource resource = resourceDAO.find(resourceKey);
-        if (resource == null) {
-            throw new NotFoundException("Resource '" + resourceKey + '\'');
-        }
+    protected Triple<AnyType, ExternalResource, Provision> getProvision(
+            final String anyTypeKey, final String resourceKey) {
 
         AnyType anyType = anyTypeDAO.find(anyTypeKey);
         if (anyType == null) {
-            throw new NotFoundException("AnyType '" + anyTypeKey + '\'');
+            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
         }
 
-        return resource.getProvision(anyType).
+        ExternalResource resource = resourceDAO.find(resourceKey);
+        if (resource == null) {
+            throw new NotFoundException("Resource '" + resourceKey + "'");
+        }
+        Provision provision = resource.getProvision(anyType.getKey()).
                 orElseThrow(() -> new NotFoundException(
-                "Provision on resource '" + resourceKey + "' for type '" + anyTypeKey + "'"));
+                "Provision for " + anyType + " on Resource '" + resourceKey + "'"));
+        if (provision.getMapping() == null) {
+            throw new NotFoundException("Mapping for " + anyType + " on Resource '" + resourceKey + "'");
+        }
+
+        return Triple.of(anyType, resource, provision);
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_GET_CONNOBJECT + "')")
@@ -314,42 +319,46 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             final String anyTypeKey,
             final String anyKey) {
 
-        Provision provision = getProvision(key, anyTypeKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, key);
 
         // 1. find any
-        Any<?> any = anyUtilsFactory.getInstance(provision.getAnyType().getKind()).dao().authFind(anyKey);
+        Any<?> any = anyUtilsFactory.getInstance(triple.getLeft().getKind()).dao().authFind(anyKey);
         if (any == null) {
-            throw new NotFoundException(provision.getAnyType() + " " + anyKey);
+            throw new NotFoundException(triple.getLeft() + " " + anyKey);
         }
 
         // 2.get ConnObjectKey value
-        return mappingManager.getConnObjectKeyValue(any, provision).
+        return mappingManager.getConnObjectKeyValue(any, triple.getMiddle(), triple.getRight()).
                 orElseThrow(() -> new NotFoundException(
                 "No ConnObjectKey value found for " + anyTypeKey + " " + anyKey + " on resource '" + key + "'"));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_GET_CONNOBJECT + "')")
     @Transactional(readOnly = true)
-    public ConnObjectTO readConnObjectByAnyKey(
+    public ConnObject readConnObjectByAnyKey(
             final String key,
             final String anyTypeKey,
             final String anyKey) {
 
-        Provision provision = getProvision(key, anyTypeKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, key);
 
         // 1. find any
-        Any<?> any = anyUtilsFactory.getInstance(provision.getAnyType().getKind()).dao().authFind(anyKey);
+        Any<?> any = anyUtilsFactory.getInstance(triple.getLeft().getKind()).dao().authFind(anyKey);
         if (any == null) {
-            throw new NotFoundException(provision.getAnyType() + " " + anyKey);
+            throw new NotFoundException(triple.getLeft() + " " + anyKey);
         }
 
         // 2. find on resource
         List<ConnectorObject> connObjs = outboundMatcher.match(
-                connectorManager.getConnector(provision.getResource()), any, provision, Optional.empty());
+                connectorManager.getConnector(triple.getMiddle()),
+                any,
+                triple.getMiddle(),
+                triple.getRight(),
+                Optional.empty());
         if (connObjs.isEmpty()) {
             throw new NotFoundException(
-                    "Object " + any + " with class " + provision.getObjectClass()
-                    + " not found on resource " + provision.getResource().getKey());
+                    "Object " + any + " with class " + triple.getRight().getObjectClass()
+                    + " not found on resource " + triple.getMiddle().getKey());
         }
 
         if (connObjs.size() > 1) {
@@ -359,40 +368,43 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         }
 
         return ConnObjectUtils.getConnObjectTO(
-                outboundMatcher.getFIQL(connObjs.get(0), provision), connObjs.get(0).getAttributes());
+                outboundMatcher.getFIQL(connObjs.get(0), triple.getMiddle(), triple.getRight()),
+                connObjs.get(0).getAttributes());
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_GET_CONNOBJECT + "')")
     @Transactional(readOnly = true)
-    public ConnObjectTO readConnObjectByConnObjectKeyValue(
+    public ConnObject readConnObjectByConnObjectKeyValue(
             final String key,
             final String anyTypeKey,
             final String connObjectKeyValue) {
 
-        Provision provision = getProvision(key, anyTypeKey);
+        Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, key);
 
-        MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision).
+        Item connObjectKeyItem = MappingUtils.getConnObjectKeyItem(triple.getRight()).
                 orElseThrow(() -> new NotFoundException(
-                "ConnObjectKey mapping for " + provision.getAnyType().getKey()
-                + " on resource '" + provision.getResource().getKey() + "'"));
+                "ConnObjectKey mapping for " + triple.getLeft().getKey()
+                + " on resource '" + triple.getMiddle().getKey() + "'"));
 
         return outboundMatcher.matchByConnObjectKeyValue(
-                connectorManager.getConnector(provision.getResource()),
+                connectorManager.getConnector(triple.getMiddle()),
                 connObjectKeyItem,
                 connObjectKeyValue,
-                provision,
+                triple.getMiddle(),
+                triple.getRight(),
                 Optional.empty(),
                 Optional.empty()).
                 map(connectorObject -> ConnObjectUtils.getConnObjectTO(
-                outboundMatcher.getFIQL(connectorObject, provision), connectorObject.getAttributes())).
+                outboundMatcher.getFIQL(connectorObject, triple.getMiddle(), triple.getRight()),
+                connectorObject.getAttributes())).
                 orElseThrow(() -> new NotFoundException(
-                "Object " + connObjectKeyValue + " with class " + provision.getObjectClass()
-                + " not found on resource " + provision.getResource().getKey()));
+                "Object " + connObjectKeyValue + " with class " + triple.getRight().getObjectClass()
+                + " not found on resource " + triple.getMiddle().getKey()));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_LIST_CONNOBJECT + "')")
     @Transactional(readOnly = true)
-    public Pair<SearchResult, List<ConnObjectTO>> searchConnObjects(
+    public Pair<SearchResult, List<ConnObject>> searchConnObjects(
             final Filter filter,
             final Set<String> moreAttrsToGet,
             final String key,
@@ -415,21 +427,24 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             }
 
             provision = null;
-            objectClass = resource.getOrgUnit().getObjectClass();
+            objectClass = new ObjectClass(resource.getOrgUnit().getObjectClass());
             options = MappingUtils.buildOperationOptions(
                     resource.getOrgUnit().getItems().stream(), moreAttrsToGet.toArray(String[]::new));
         } else {
-            provision = getProvision(key, anyTypeKey);
-            resource = provision.getResource();
-            objectClass = provision.getObjectClass();
+            Triple<AnyType, ExternalResource, Provision> triple = getProvision(anyTypeKey, key);
+
+            provision = triple.getRight();
+            resource = triple.getMiddle();
+            objectClass = new ObjectClass(provision.getObjectClass());
 
-            Stream<MappingItem> mapItems = Stream.concat(
+            Stream<Item> mapItems = Stream.concat(
                     provision.getMapping().getItems().stream(),
-                    virSchemaDAO.findByProvision(provision).stream().map(VirSchema::asLinkingMappingItem));
+                    virSchemaDAO.find(resource.getKey(), triple.getLeft().getKey()).
+                            stream().map(VirSchema::asLinkingMappingItem));
             options = MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(String[]::new));
         }
 
-        List<ConnObjectTO> connObjects = new ArrayList<>();
+        List<ConnObject> connObjects = new ArrayList<>();
         SearchResult searchResult = connectorManager.getConnector(resource).
                 search(objectClass, filter, new SearchResultsHandler() {
 
@@ -438,7 +453,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                     @Override
                     public boolean handle(final ConnectorObject connectorObject) {
                         connObjects.add(ConnObjectUtils.getConnObjectTO(
-                                provision == null ? null : outboundMatcher.getFIQL(connectorObject, provision),
+                                provision == null
+                                        ? null : outboundMatcher.getFIQL(connectorObject, resource, provision),
                                 connectorObject.getAttributes()));
                         // safety protection against uncontrolled result size
                         count++;
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
index af88fc0ab7..248351ac4b 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ReconciliationLogicTest.java
@@ -59,9 +59,8 @@ public class ReconciliationLogicTest extends AbstractTest {
         CSVPullSpec spec = new CSVPullSpec.Builder(AnyTypeKind.USER.name(), "username").build();
         InputStream csv = getClass().getResourceAsStream("/test1.csv");
 
-        List<ProvisioningReport> results = AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> {
-            return reconciliationLogic.pull(spec, csv);
-        });
+        List<ProvisioningReport> results =
+                AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> reconciliationLogic.pull(spec, csv));
         assertEquals(2, results.size());
 
         assertEquals(AnyTypeKind.USER.name(), results.get(0).getAnyType());
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java
new file mode 100644
index 0000000000..3da106ff11
--- /dev/null
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.logic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.OrgUnit;
+import org.apache.syncope.common.lib.to.Provision;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.ConnectorManager;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional("Master")
+public class ResourceLogicTest extends AbstractTest {
+
+    @BeforeAll
+    public static void setAuthContext() {
+        List<GrantedAuthority> authorities = IdMEntitlement.values().stream().
+                map(entitlement -> new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM)).
+                collect(Collectors.toList());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new org.springframework.security.core.userdetails.User(
+                        "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails(SyncopeConstants.MASTER_DOMAIN, null));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    @AfterAll
+    public static void unsetAuthContext() {
+        SecurityContextHolder.getContext().setAuthentication(null);
+    }
+
+    private static ResourceTO buildResourceTO(final String resourceKey) {
+        ResourceTO resourceTO = new ResourceTO();
+
+        resourceTO.setKey(resourceKey);
+        resourceTO.setConnector("5ffbb4ac-a8c3-4b44-b699-11b398a1ba08");
+
+        Provision provisionTO = new Provision();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        Mapping mapping = new Mapping();
+        provisionTO.setMapping(mapping);
+
+        Item item = new Item();
+        item.setExtAttrName("userId");
+        item.setIntAttrName("userId");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        item = new Item();
+        item.setExtAttrName("username");
+        item.setIntAttrName("key");
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = new Item();
+        item.setExtAttrName("fullname");
+        item.setIntAttrName("cn");
+        item.setConnObjectKey(false);
+        item.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.add(item);
+
+        return resourceTO;
+    }
+
+    @Autowired
+    private ResourceLogic logic;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Test
+    public void updateChangePurpose() {
+        ResourceTO ws1 = logic.read("ws-target-resource-1");
+        assertNotNull(ws1);
+
+        Mapping ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
+        // change purpose from NONE to BOTH
+        ws1NewUMapping.getItems().stream().
+                filter(itemTO -> "firstname".equals(itemTO.getIntAttrName())).
+                forEach(itemTO -> itemTO.setPurpose(MappingPurpose.BOTH));
+        ws1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);
+
+        ws1 = logic.update(ws1);
+        assertNotNull(ws1);
+    }
+
+    @Test
+    public void updateChangeOverrideCapabilities() {
+        ResourceTO ldap = logic.read("resource-ldap");
+        assertNotNull(ldap);
+        assertFalse(ldap.isOverrideCapabilities());
+        assertTrue(ldap.getCapabilitiesOverride().isEmpty());
+
+        ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
+        ldap = logic.update(ldap);
+        assertNotNull(ldap);
+        assertFalse(ldap.isOverrideCapabilities());
+        assertEquals(1, ldap.getCapabilitiesOverride().size());
+        assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
+
+        ldap.setOverrideCapabilities(true);
+        ldap = logic.update(ldap);
+        assertNotNull(ldap);
+        assertTrue(ldap.isOverrideCapabilities());
+        assertEquals(1, ldap.getCapabilitiesOverride().size());
+        assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
+
+        ldap.getCapabilitiesOverride().clear();
+        ldap.setOverrideCapabilities(false);
+        logic.update(ldap);
+    }
+
+    @Test
+    public void orgUnit() {
+        ResourceTO resourceTO = buildResourceTO("ws-orgunit");
+        assertNull(resourceTO.getOrgUnit());
+        assertNull(resourceTO.getPropagationPriority());
+
+        resourceTO = logic.create(resourceTO);
+        entityManager().flush();
+        assertNull(resourceTO.getOrgUnit());
+
+        OrgUnit orgUnit = new OrgUnit();
+        orgUnit.setConnObjectLink("'ou=' + name + ',o=isp'");
+        orgUnit.setObjectClass("organizationalUnit");
+
+        Item item = new Item();
+        item.setIntAttrName("name");
+        item.setExtAttrName("ou");
+        item.setMandatoryCondition("true");
+        item.setPurpose(MappingPurpose.BOTH);
+        orgUnit.setConnObjectKeyItem(item);
+
+        resourceTO.setOrgUnit(orgUnit);
+        logic.update(resourceTO);
+        entityManager().flush();
+        assertNull(resourceTO.getPropagationPriority());
+
+        resourceTO = logic.read("ws-orgunit");
+        assertNotNull(resourceTO.getOrgUnit());
+
+        resourceTO.setOrgUnit(null);
+        resourceTO.setPropagationPriority(11);
+        logic.update(resourceTO);
+        entityManager().flush();
+
+        resourceTO = logic.read("ws-orgunit");
+        assertNull(resourceTO.getOrgUnit());
+        assertEquals(11, resourceTO.getPropagationPriority());
+    }
+
+    @Test
+    public void setLatestSyncToken() {
+        ConnectorManager connectorManager = mock(ConnectorManager.class);
+        when(connectorManager.getConnector(any(ExternalResource.class))).thenAnswer(ic -> {
+            Connector connector = mock(Connector.class);
+            when(connector.getLatestSyncToken(any(ObjectClass.class))).thenAnswer(ic2 -> new SyncToken("tokenValue"));
+            return connector;
+        });
+
+        ResourceTO resourceTO = logic.create(buildResourceTO("lss"));
+        assertNotNull(resourceTO);
+        assertNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken());
+
+        ResourceLogic resourceLogic = new ResourceLogic(
+                resourceDAO, anyTypeDAO, null, null, null, null, null, null, null, connectorManager, null);
+
+        resourceLogic.setLatestSyncToken(resourceTO.getKey(), AnyTypeKind.USER.name());
+        entityManager().flush();
+
+        resourceTO = logic.read(resourceTO.getKey());
+        assertNotNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken());
+    }
+}
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index b9f092d327..e8b268f229 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -21,8 +21,8 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.net.URI;
 import java.util.List;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnIdBundle;
+import org.apache.syncope.common.lib.to.ConnIdObjectClass;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
@@ -53,12 +53,12 @@ public class ConnectorServiceImpl extends AbstractService implements ConnectorSe
     }
 
     @Override
-    public List<ConnBundleTO> getBundles(final String lang) {
+    public List<ConnIdBundle> getBundles(final String lang) {
         return logic.getBundles(lang);
     }
 
     @Override
-    public List<ConnIdObjectClassTO> buildObjectClassInfo(
+    public List<ConnIdObjectClass> buildObjectClassInfo(
             final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
 
         return logic.buildObjectClassInfo(connInstanceTO, includeSpecial);
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index fa4e7a891c..b02a45ab37 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -33,8 +33,8 @@ import org.apache.cxf.jaxrs.ext.search.SearchBean;
 import org.apache.cxf.jaxrs.ext.search.SearchCondition;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.PagedConnObjectTOResult;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.to.PagedConnObjectResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -101,14 +101,14 @@ public class ResourceServiceImpl extends AbstractService implements ResourceServ
     }
 
     @Override
-    public ConnObjectTO readConnObject(final String key, final String anyTypeKey, final String value) {
+    public ConnObject readConnObject(final String key, final String anyTypeKey, final String value) {
         return SyncopeConstants.UUID_PATTERN.matcher(value).matches()
                 ? logic.readConnObjectByAnyKey(key, anyTypeKey, value)
                 : logic.readConnObjectByConnObjectKeyValue(key, anyTypeKey, value);
     }
 
     @Override
-    public PagedConnObjectTOResult searchConnObjects(
+    public PagedConnObjectResult searchConnObjects(
             final String key, final String anyTypeKey, final ConnObjectTOQuery query) {
 
         Filter filter = null;
@@ -134,7 +134,7 @@ public class ResourceServiceImpl extends AbstractService implements ResourceServ
             }
         }
 
-        Pair<SearchResult, List<ConnObjectTO>> list = logic.searchConnObjects(
+        Pair<SearchResult, List<ConnObject>> list = logic.searchConnObjects(
                 filter,
                 moreAttrsToGet,
                 key,
@@ -143,7 +143,7 @@ public class ResourceServiceImpl extends AbstractService implements ResourceServ
                 query.getPagedResultsCookie(),
                 getOrderByClauses(query.getOrderBy()));
 
-        PagedConnObjectTOResult result = new PagedConnObjectTOResult();
+        PagedConnObjectResult result = new PagedConnObjectResult();
         if (list.getLeft() != null) {
             result.setAllResultsReturned(list.getLeft().isAllResultsReturned());
             result.setPagedResultsCookie(list.getLeft().getPagedResultsCookie());
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
index 6ad2c22f36..487bb94c42 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
@@ -190,7 +190,7 @@ public class ImplementationLogic extends AbstractTransactionalLogic<Implementati
                 break;
 
             case IdRepoImplementationType.ITEM_TRANSFORMER:
-                inUse = !resourceDAO.findByTransformer(implementation).isEmpty();
+                inUse = resourceDAO.anyItemHaving(implementation);
                 break;
 
             case IdRepoImplementationType.TASKJOB_DELEGATE:
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/validation/InvalidEntityException.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/validation/InvalidEntityException.java
index a7a3cfcc0b..9e70892098 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/validation/InvalidEntityException.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/validation/InvalidEntityException.java
@@ -21,9 +21,11 @@ package org.apache.syncope.core.persistence.api.attrvalue.validation;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import javax.validation.ConstraintViolation;
 import javax.validation.ValidationException;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 
 /**
@@ -53,7 +55,7 @@ public class InvalidEntityException extends ValidationException {
 
         this.entityClassSimpleName = entityClass.getSimpleName();
 
-        entityViolationType.setMessage(message.trim());
+        entityViolationType.setMessage(Optional.ofNullable(message).map(String::trim).orElse(StringUtils.EMPTY));
 
         this.violations.put(entityClass, EnumSet.noneOf(EntityViolationType.class));
         this.violations.get(entityClass).add(entityViolationType);
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 85dfa67d92..da128ed688 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,11 +25,11 @@ import java.util.Optional;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 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.Schema;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface AnyDAO<A extends Any<?>> extends DAO<A> {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index 15fc6dcd7e..1b660971a1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -25,11 +25,11 @@ import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 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.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Relationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 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;
 
 public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
index c0f0dca2ef..9052401e3a 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
@@ -25,6 +25,4 @@ public interface DAO<E extends Entity> {
     void refresh(E entity);
 
     void detach(E entity);
-
-    void clear();
 }
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 ecde5f10b5..3242518ab9 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
@@ -19,12 +19,11 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 
 public interface ExternalResourceDAO extends DAO<ExternalResource> {
 
@@ -36,7 +35,7 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> {
 
     List<Provision> findProvisionsByAuxClass(AnyTypeClass anyTypeClass);
 
-    List<MappingItem> findByTransformer(Implementation transformer);
+    boolean anyItemHaving(Implementation transformer);
 
     List<ExternalResource> findByPropagationActions(Implementation propagationActions);
 
@@ -49,5 +48,4 @@ public interface ExternalResourceDAO extends DAO<ExternalResource> {
     void deleteMapping(String schemaName);
 
     void delete(String key);
-
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
index 9a444d353e..fd5c2f1c05 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
@@ -19,13 +19,13 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface PolicyDAO extends DAO<Policy> {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PullCorrelationRule.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PullCorrelationRule.java
index 47b2bd732e..4be32ef553 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PullCorrelationRule.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PullCorrelationRule.java
@@ -20,10 +20,10 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.Optional;
 import org.apache.syncope.common.lib.policy.PullCorrelationRuleConf;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.MatchType;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 
 /**
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PushCorrelationRule.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PushCorrelationRule.java
index c4c354017b..88dd30a971 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PushCorrelationRule.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PushCorrelationRule.java
@@ -20,8 +20,9 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.function.BiFunction;
 import org.apache.syncope.common.lib.policy.PushCorrelationRuleConf;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.identityconnectors.framework.common.objects.filter.Filter;
@@ -46,10 +47,11 @@ public interface PushCorrelationRule {
      * the given provision.
      *
      * @param any user, group or any object
+     * @param resource external resource
      * @param provision resource provision
      * @return filter.
      */
-    Filter getFilter(Any<?> any, Provision provision);
+    Filter getFilter(Any<?> any, ExternalResource resource, Provision provision);
 
     /**
      * Returns a FIQL string to match the given connector object when searching into the external resource identified by
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 9daabb12a1..7a3b5cbaa8 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
@@ -20,10 +20,10 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import java.util.regex.Pattern;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface RealmDAO extends DAO<Realm> {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
index f4b3e74c00..5fe51717af 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
@@ -25,9 +25,9 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ExecStatus;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index 98302bfc60..d8827aeeee 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -24,10 +24,10 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
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 1cf6475283..da13e59c73 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
@@ -19,10 +19,12 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 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> {
 
-    List<VirSchema> findByProvision(Provision provision);
+    List<String> find(ExternalResource resource);
+
+    List<VirSchema> find(String resource, String anyType);
 }
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 5ee01f9853..b422113ad3 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
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.time.OffsetDateTime;
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface Any<P extends PlainAttr<?>> extends Attributable<P>, Entity {
 
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 d9b53c3b1a..4c65c764f5 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
@@ -25,7 +25,6 @@ import org.apache.syncope.common.lib.request.AnyUR;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface AnyUtils {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
index 258ea314fe..57bbda6f06 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface ConnInstance extends Entity {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
similarity index 84%
rename from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
rename to core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
index 8758cb6e91..370c1932cc 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
@@ -16,18 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.persistence.api.entity.resource;
+package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import org.apache.syncope.common.lib.to.OrgUnit;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
@@ -107,15 +105,11 @@ public interface ExternalResource extends ProvidedKeyEntity {
 
     void setRandomPwdIfNotProvided(boolean condition);
 
-    boolean add(Provision provision);
+    Optional<Provision> getProvision(String anyType);
 
-    Optional<? extends Provision> getProvision(String anyType);
+    Optional<Provision> getProvision(ObjectClass objectClass);
 
-    Optional<? extends Provision> getProvision(AnyType anyType);
-
-    Optional<? extends Provision> getProvision(ObjectClass objectClass);
-
-    List<? extends Provision> getProvisions();
+    List<Provision> getProvisions();
 
     OrgUnit getOrgUnit();
 
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
deleted file mode 100644
index 6689bfcf66..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/LinkingMappingItem.java
+++ /dev/null
@@ -1,143 +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;
-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;
-
-/**
- * {@link MappingItem} implementation for usage within {@link VirSchema#asLinkingMappingItem()} implementations.
- */
-public class LinkingMappingItem implements MappingItem {
-
-    private static final long serialVersionUID = 327455459536715529L;
-
-    private final VirSchema virSchema;
-
-    public LinkingMappingItem(final VirSchema virSchema) {
-        this.virSchema = virSchema;
-    }
-
-    @Override
-    public String getKey() {
-        return null;
-    }
-
-    @Override
-    public Mapping getMapping() {
-        return virSchema.getProvision().getMapping();
-    }
-
-    @Override
-    public void setMapping(final Mapping mapping) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public String getExtAttrName() {
-        return virSchema.getExtAttrName();
-    }
-
-    @Override
-    public void setExtAttrName(final String extAttrName) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public String getIntAttrName() {
-        return virSchema.getKey();
-    }
-
-    @Override
-    public void setIntAttrName(final String intAttrName) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return virSchema.getMandatoryCondition();
-    }
-
-    @Override
-    public void setMandatoryCondition(final String condition) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public MappingPurpose getPurpose() {
-        return virSchema.isReadonly() ? MappingPurpose.PULL : MappingPurpose.BOTH;
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public boolean isConnObjectKey() {
-        return false;
-    }
-
-    @Override
-    public void setConnObjectKey(final boolean connObjectKey) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public boolean isPassword() {
-        return false;
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public String getPropagationJEXLTransformer() {
-        return null;
-    }
-
-    @Override
-    public void setPropagationJEXLTransformer(final String propagationJEXLTransformer) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public String getPullJEXLTransformer() {
-        return null;
-    }
-
-    @Override
-    public void setPullJEXLTransformer(final String pullJEXLTransformer) {
-        // RO instance, nothing to do
-    }
-
-    @Override
-    public boolean add(final Implementation transformer) {
-        return false;
-    }
-
-    @Override
-    public List<? extends Implementation> getTransformers() {
-        return List.of();
-    }
-}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
index 808547243e..42249ce9a4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java
@@ -25,7 +25,6 @@ import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AttrReleasePolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface Realm extends Entity {
 
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 65cc11dc0a..a16c994778 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,20 +18,33 @@
  */
 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;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.types.MappingPurpose;
 
 public interface VirSchema extends Schema {
 
     void setReadonly(boolean readonly);
 
-    Provision getProvision();
+    ExternalResource getResource();
 
-    void setProvision(Provision provision);
+    void setResource(ExternalResource resource);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
 
     String getExtAttrName();
 
     void setExtAttrName(String extAttrName);
 
-    MappingItem asLinkingMappingItem();
+    default Item asLinkingMappingItem() {
+        Item item = new Item();
+        item.setExtAttrName(getExtAttrName());
+        item.setIntAttrName(getKey());
+        item.setMandatoryCondition(getMandatoryCondition());
+        item.setPurpose(isReadonly() ? MappingPurpose.PULL : MappingPurpose.BOTH);
+        item.setConnObjectKey(false);
+        item.setPassword(false);
+        return item;
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepo.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepo.java
index fdab6475eb..3fbc53331a 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepo.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepo.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.entity.am;
 
 import java.util.List;
 import org.apache.syncope.common.lib.attr.AttrRepoConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AttrRepoState;
 import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity;
 
@@ -41,7 +42,5 @@ public interface AttrRepo extends ProvidedKeyEntity {
 
     void setConf(AttrRepoConf conf);
 
-    List<? extends AttrRepoItem> getItems();
-
-    boolean add(AttrRepoItem item);
+    List<Item> getItems();
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepoItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepoItem.java
deleted file mode 100644
index 43213ef449..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AttrRepoItem.java
+++ /dev/null
@@ -1,28 +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.am;
-
-import org.apache.syncope.core.persistence.api.entity.resource.Item;
-
-public interface AttrRepoItem extends Item {
-
-    AttrRepo getAttrRepo();
-
-    void setAttrRepo(AttrRepo attrRepo);
-}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModule.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModule.java
index 5edc23e488..62c443cf3b 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModule.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModule.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.entity.am;
 
 import java.util.List;
 import org.apache.syncope.common.lib.auth.AuthModuleConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AuthModuleState;
 import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity;
 
@@ -41,7 +42,5 @@ public interface AuthModule extends ProvidedKeyEntity {
 
     void setConf(AuthModuleConf conf);
 
-    List<? extends AuthModuleItem> getItems();
-
-    boolean add(AuthModuleItem item);
+    List<Item> getItems();
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModuleItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModuleItem.java
deleted file mode 100644
index d7168abd25..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/AuthModuleItem.java
+++ /dev/null
@@ -1,28 +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.am;
-
-import org.apache.syncope.core.persistence.api.entity.resource.Item;
-
-public interface AuthModuleItem extends Item {
-
-    AuthModule getAuthModule();
-
-    void setAuthModule(AuthModule authModule);
-}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
index af09b391dc..b308c5450a 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/AccountPolicy.java
@@ -20,8 +20,8 @@ package org.apache.syncope.core.persistence.api.entity.policy;
 
 import java.util.List;
 import java.util.Set;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface AccountPolicy extends Policy {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
index 4faf109ebb..353682fe4f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PullPolicy.java
@@ -20,13 +20,12 @@ package org.apache.syncope.core.persistence.api.entity.policy;
 
 import java.util.List;
 import java.util.Optional;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 
 public interface PullPolicy extends ProvisioningPolicy {
 
     boolean add(PullCorrelationRuleEntity rule);
 
-    Optional<? extends PullCorrelationRuleEntity> getCorrelationRule(AnyType anyType);
+    Optional<? extends PullCorrelationRuleEntity> getCorrelationRule(String anyType);
 
     List<? extends PullCorrelationRuleEntity> getCorrelationRules();
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PushPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PushPolicy.java
index 9480ef5ef6..79c5b12bf5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PushPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/policy/PushPolicy.java
@@ -20,13 +20,12 @@ package org.apache.syncope.core.persistence.api.entity.policy;
 
 import java.util.List;
 import java.util.Optional;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 
 public interface PushPolicy extends ProvisioningPolicy {
 
     boolean add(PushCorrelationRuleEntity rule);
 
-    Optional<? extends PushCorrelationRuleEntity> getCorrelationRule(AnyType anyType);
+    Optional<? extends PushCorrelationRuleEntity> getCorrelationRule(String anyType);
 
     List<? extends PushCorrelationRuleEntity> getCorrelationRules();
 }
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
deleted file mode 100644
index b46cab5952..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Item.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.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;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-
-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);
-
-    boolean add(Implementation transformer);
-
-    List<? extends Implementation> getTransformers();
-}
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
deleted file mode 100644
index ce7abaa8ae..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
+++ /dev/null
@@ -1,42 +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.resource;
-
-import java.util.List;
-import java.util.Optional;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-
-public interface Mapping extends Entity {
-
-    Provision getProvision();
-
-    void setProvision(Provision provision);
-
-    String getConnObjectLink();
-
-    void setConnObjectLink(String connObjectLink);
-
-    boolean add(MappingItem item);
-
-    Optional<? extends MappingItem> getConnObjectKeyItem();
-
-    void setConnObjectKeyItem(MappingItem item);
-
-    List<? extends MappingItem> getItems();
-}
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
deleted file mode 100644
index 24dc15df42..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
+++ /dev/null
@@ -1,27 +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.resource;
-
-public interface MappingItem extends Item {
-
-    Mapping getMapping();
-
-    void setMapping(Mapping mapping);
-
-}
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
deleted file mode 100644
index 52e209b96e..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnit.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.resource;
-
-import java.util.List;
-import java.util.Optional;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-public interface OrgUnit extends Entity {
-
-    ExternalResource getResource();
-
-    void setResource(ExternalResource resource);
-
-    ObjectClass getObjectClass();
-
-    void setObjectClass(ObjectClass objectClass);
-
-    SyncToken getSyncToken();
-
-    String getSerializedSyncToken();
-
-    void setSyncToken(SyncToken syncToken);
-
-    boolean isIgnoreCaseMatch();
-
-    void setIgnoreCaseMatch(boolean ignoreCaseMatch);
-
-    String getConnObjectLink();
-
-    void setConnObjectLink(String connObjectLink);
-
-    boolean add(OrgUnitItem item);
-
-    Optional<? extends OrgUnitItem> getConnObjectKeyItem();
-
-    void setConnObjectKeyItem(OrgUnitItem item);
-
-    List<? extends OrgUnitItem> getItems();
-}
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
deleted file mode 100644
index d25e0bcff3..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/OrgUnitItem.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.resource;
-
-public interface OrgUnitItem extends Item {
-
-    OrgUnit getOrgUnit();
-
-    void setOrgUnit(OrgUnit orgUnit);
-}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java
deleted file mode 100644
index 5dde2015f8..0000000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity.resource;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-public interface Provision extends Entity {
-
-    ExternalResource getResource();
-
-    void setResource(ExternalResource resource);
-
-    AnyType getAnyType();
-
-    void setAnyType(AnyType anyType);
-
-    ObjectClass getObjectClass();
-
-    void setObjectClass(ObjectClass objectClass);
-
-    boolean add(AnyTypeClass anyTypeClass);
-
-    List<? extends AnyTypeClass> getAuxClasses();
-
-    SyncToken getSyncToken();
-
-    String getSerializedSyncToken();
-
-    void setSyncToken(SyncToken syncToken);
-
-    boolean isIgnoreCaseMatch();
-
-    void setIgnoreCaseMatch(boolean ignoreCaseMatch);
-
-    PlainSchema getUidOnCreate();
-
-    void setUidOnCreate(PlainSchema uidOnCreate);
-
-    Mapping getMapping();
-
-    void setMapping(Mapping mapping);
-}
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 e5709ca154..b8b71d1e5d 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
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.api.entity.task;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.identityconnectors.framework.common.objects.Attribute;
 
 public interface PropagationTask extends Task {
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
index 743c08b790..e7f9fd1e33 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
@@ -21,8 +21,8 @@ package org.apache.syncope.core.persistence.api.entity.task;
 import java.util.List;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface ProvisioningTask extends SchedTask {
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
index d1bceb0974..7e932de373 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PullTask.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.persistence.api.entity.task;
 import java.util.List;
 import java.util.Optional;
 import org.apache.syncope.common.lib.types.PullMode;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 
@@ -41,7 +40,7 @@ public interface PullTask extends ProvisioningTask {
 
     boolean add(AnyTemplatePullTask template);
 
-    Optional<? extends AnyTemplatePullTask> getTemplate(AnyType anyType);
+    Optional<? extends AnyTemplatePullTask> getTemplate(String anyType);
 
     List<? extends AnyTemplatePullTask> getTemplates();
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
index 0485f05b6c..864505b93d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/LinkedAccount.java
@@ -20,8 +20,8 @@ package org.apache.syncope.core.persistence.api.entity.user;
 
 import java.util.Set;
 import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
 public interface LinkedAccount extends Account, Attributable<LAPlainAttr> {
 
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index fb4299750b..c2372307b6 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -53,18 +53,18 @@ under the License.
               jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf","authModules":["LdapAuthenticationTest"]}'/>
 
   <!-- Access policies -->
-  <AccessPolicy id="419935c7-deb3-40b3-8a9a-683037e523a2" name="MyDefaultAccessPolicyConf"
-                jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf","name":"MyDefaultAccessPolicyConf","enabled":true,"ssoEnabled":true}'/>
+  <AccessPolicy aporder="0" ssoEnabled="1" name="MyDefaultAccessPolicyConf" caseInsensitive="1" id="419935c7-deb3-40b3-8a9a-683037e523a2" enabled="1" requireAllAttributes="1"/>
 
   <!-- Attr Release Policies -->
-  <AttrReleasePolicy id="319935c7-deb3-40b3-8a9a-683037e523a2" name="AllowedAttrReleasePolicy"
-                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"AllowedAttrReleasePolicy","allowedAttributes":["cn","givenName","uid"]}'/>
-  <AttrReleasePolicy id="219935c7-deb3-40b3-8a9a-683037e523a2" name="DenyAttrReleasePolicy"
-                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"DenyAttrReleasePolicyConf"}'/>
+  <AttrReleasePolicy arporder="0" name="DenyAttrReleasePolicy" id="219935c7-deb3-40b3-8a9a-683037e523a2"
+                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf","allowedAttrs":[],"excludedAttrs":[],"includeOnlyAttrs":[],"principalIdAttr":null,"principalAttrRepoConf":{"mergingStrategy":"MULTIVALUED","ignoreResolvedAttributes":false,"expiration":0,"timeUnit":"HOURS","attrRepos":[]}}'/>
+  <AttrReleasePolicy arporder="0" name="AllowedAttrReleasePolicy" id="319935c7-deb3-40b3-8a9a-683037e523a2"
+                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf","allowedAttrs":["cn","givenName","uid"],"excludedAttrs":[],"includeOnlyAttrs":[],"principalIdAttr":null,"principalAttrRepoConf":{"mergingStrategy":"MULTIVALUED","ignoreResolvedAttributes":false,"expiration":0,"timeUnit":"HOURS","attrRepos":[]}}'/>
       
   <!-- Authentication modules -->
   <AuthModule id="DefaultLDAPAuthModule" authModuleState="ACTIVE"
-              description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}'/>
+              description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}'
+              items='[{"intAttrName":"mail","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"givenName","extAttrName":"givenName","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"sn","extAttrName":"sn","conn [...]
   <AuthModule id="DefaultJDBCAuthModule" authModuleState="ACTIVE"
               description="JDBC auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","sql":"SELECT * FROM users_table WHERE name=?", "fieldPassword": "password"}'/>
   <AuthModule id="DefaultGoogleMfaAuthModule" authModuleState="ACTIVE"
@@ -82,42 +82,22 @@ under the License.
   <AuthModule id="DefaultStaticAuthModule" authModuleState="ACTIVE"
               description="Static auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.StaticAuthModuleConf","users":{"syncope1": "$cynop3"}}'/>
   <AuthModule id="DefaultSyncopeAuthModule" authModuleState="ACTIVE"
-              description="Syncope auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","domain":"Master"}'/>
+              description="Syncope auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","domain":"Master"}'
+              items='[{"intAttrName":"syncopeUserAttr_surname","extAttrName":"family_name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"syncopeUserAttr_fullname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAtt [...]
   <AuthModule id="DefaultU2FAuthModule" authModuleState="ACTIVE"
               description="U2F auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.U2FAuthModuleConf","expireDevices":40}'/>
 
-  <AuthModuleItem id="26678936-af09-48b8-a789-36af0918b87d" extAttrName="family_name" intAttrName="syncopeUserAttr_surname"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="a66ed3b1-07be-4a6e-aed3-b107be8a6e75" extAttrName="name" intAttrName="syncopeUserAttr_fullname"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="edc26674-fac5-4a60-8266-74fac5ca6020" extAttrName="given_name" intAttrName="syncopeUserAttr_firstname" 
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="520eeba7-e00a-4221-8eeb-a7e00aa22159" extAttrName="email" intAttrName="syncopeUserAttr_email"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="8360509b-7d8e-4796-aa79-3c5ccc8671e6" extAttrName="groups" intAttrName="syncopeUserMemberships"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-
-  <AuthModuleItem id="8437a40d-d74e-400c-9628-72eba9e30a13" extAttrName="mail" intAttrName="mail"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="1b7a8347-810b-44f2-85ae-58f9e4bedc37" extAttrName="givenName" intAttrName="givenName"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="b06cd5fe-c86b-48d4-8acc-4a46c12bea41" extAttrName="sn" intAttrName="sn" 
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="a1933059-e64f-409f-a86c-5b54da21787e" extAttrName="cn" intAttrName="cn"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-
   <!-- Attribute repositories -->
   <AttrRepo id="DefaultLDAPAttrRepo" attrRepoState="ACTIVE"
             description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:1389","bindDn":"uid=admin,ou=system","bindCredential":"secret","baseDn":"ou=People,o=isp","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/>
   <AttrRepo id="DefaultJDBCAttrRepo" attrRepoState="ACTIVE"
             description="JDBC attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.JDBCAttrRepoConf","sql":"SELECT * FROM table WHERE name=?","dialect":"org.hibernate.dialect.H2Dialect","driverClass":"org.h2.Driver","url":"jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1","user":"username","password":"password","singleRow":true,"requireAllAttributes":true,"caseCanonicalization":"NONE","queryType":"AND","columnMappings":{},"username":[],"attributes":{},"caseInsensitiveQueryAttributes [...]
   <AttrRepo id="DefaultStubAttrRepo" attrRepoState="ACTIVE"
-            description="Stub attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.StubAttrRepoConf","attributes":{"attr1":"value1"}}'/>
+            description="Stub attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.StubAttrRepoConf","attributes":{"attr1":"value1"}}'
+            items='[{"intAttrName":"attr1","extAttrName":"identifier","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}]'/>
   <AttrRepo id="DefaultSyncopeAttrRepo" attrRepoState="ACTIVE"
             description="Syncope attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.SyncopeAttrRepoConf","domain":"Master","searchFilter":"username=={user}","basicAuthUsername":"admin","basicAuthPassword":"password","headers":{}}'/>
 
-  <AttrRepoItem id="d2d9e7be-d82b-4698-b0fb-67d480413049" extAttrName="identifier" intAttrName="attr1"
-                password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" attrRepo_id="DefaultStubAttrRepo"/>
   <RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
   <RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
   
@@ -519,11 +499,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.soap"
                 connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
                 version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false [...]
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
 
   <ConnInstance id="5aa5b8be-7521-481a-9651-c557aea078c1" displayName="H2"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -531,13 +508,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
                 version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
+                capabilities='["AUTHENTICATE","CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
 
   <ConnInstance id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" displayName="ConnInstance102"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -546,11 +518,8 @@ under the License.
                 connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
                 version="${connid.soap.version}"
                 connRequestTimeout="10"
-                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http:/ [...]
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http:/ [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
 
   <ConnInstance id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" displayName="ConnInstance103"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -566,12 +535,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.csvdir"
                 connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
                 version="${connid.csvdir.version}"
-                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lan [...]
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lan [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
     
   <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
                 bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
@@ -579,11 +544,8 @@ under the License.
                 location="${connid.location}"
                 connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
                 version="${connid.ldap.version}" 
-                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
   
   <ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -591,88 +553,84 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
                 version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
+                capabilities='["CREATE","UPDATE","SYNC","SEARCH"]'/>
   
   <ConnInstance id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" bundleName="net.tirasa.connid.bundles.db.table" 
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
                 displayName="H2-testpull" version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Pull capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage" [...]
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Pull capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage" [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
   
   <ConnInstance id="a6d017fd-a705-4507-bb7c-6ab6a6745997" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
                 adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
                 displayName="Scripted SQL" version="${connid.database.version}"
-                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schem [...]
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/>
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schem [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
   
   <ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest"
                 adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorname="net.tirasa.connid.bundles.rest.RESTConnector"
                 displayname="REST" version="${connid.rest.version}"
-                jsonconf="[{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScript&quot;,&quot;displayName&quot;:&quot;authenticateScript&quot;,&quot;helpMessage&quot;:&quot;authenticateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;contentType&quot;,&quot [...]
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SYNC"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="UPDATE"/>
+                jsonconf="[{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScript&quot;,&quot;displayName&quot;:&quot;authenticateScript&quot;,&quot;helpMessage&quot;:&quot;authenticateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;contentType&quot;,&quot [...]
+                capabilities='["AUTHENTICATE","CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
 
   <ExternalResource id="ws-target-resource-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password [...]
   <ExternalResource id="ws-target-resource-2" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    pullPolicy_id="9454b0d7-2610-400a-be82-fc23cf553dd6"/>
+                    pullPolicy_id="9454b0d7-2610-400a-be82-fc23cf553dd6"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"pas [...]
   <ExternalResource id="ws-target-resource-timeout" connector_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/services/provisioning"]}]'/>
+                    jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/services/provisioning"]}]'
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-list-mappings-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password [...]
   <ExternalResource id="ws-target-resource-list-mappings-2" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
   <ExternalResource id="ws-target-resource-delete" connector_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"username","extAttrNam [...]
   <ExternalResource id="ws-target-resource-update" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password" [...]
   <ExternalResource id="resource-testdb" connector_id="5aa5b8be-7521-481a-9651-c557aea078c1"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password" [...]
   <ExternalResource id="resource-testdb2" connector_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"pa [...]
   <ExternalResource id="resource-csv" connector_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
                     pullPolicy_id="880f8553-069b-4aed-9930-2cd53873f544"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["csv","generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"id" [...]
   <ExternalResource id="ws-target-resource-update-resetsynctoken" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":"{\"value\":null}","ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"__PASSWORD__","connObjectKey": [...]
   <ExternalResource id="resource-ldap" connector_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"&#39;uid=&#39; + username + &#39;,ou=people,o=isp&#39;","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]} [...]
   <Implementation id="LDAPMembershipPropagationActions" type="PROPAGATION_ACTIONS" engine="JAVA"
                   body="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/>
   <ExternalResourcePropAction resource_id="resource-ldap" implementation_id="LDAPMembershipPropagationActions"/>
@@ -680,51 +638,49 @@ 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":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when  [...]
-  <OrgUnit id="599a59cf-9a23-4447-9a59-cf9a2334473a" connObjectLink="syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'"
-           objectClass="organizationalUnit" resource_id="resource-ldap-orgunit" ignoreCaseMatch="0"/>
-  <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"/>
+                    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  [...]
+                    orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, &#39;ou&#39;) + &#39;,o=isp&#39;","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandato [...]
   
   <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"
-                    passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"/>
+                    passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   
-  <!-- The following three resources have been added to verify the issue SYNCOPE-68 -->
   <ExternalResource id="ws-target-resource-nopropagation2" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-nopropagation3" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-nopropagation4" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
                     
-  <!-- External resource for issue SYNCOPE-230 -->
   <ExternalResource id="resource-db-pull" connector_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
-                    enforceMandatoryCondition="0" overrideCapabilities="0"/>
+                    enforceMandatoryCondition="0" overrideCapabilities="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"SURNAME","connObjectKey":false,"password":fa [...]
                     
-  <!-- External resource for issue SYNCOPE-267 -->
   <ExternalResource id="resource-db-virattr" connector_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
-                    enforceMandatoryCondition="0" overrideCapabilities="0"/>
+                    enforceMandatoryCondition="0" overrideCapabilities="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[{"intAttrName":"virtualdata","extAttrName":"USERNAME","connObjectKey":false [...]
 
   <ExternalResource id="resource-db-scripted" connector_id="a6d017fd-a705-4507-bb7c-6ab6a6745997"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPolicy_id="89d322db-9878-420c-b49c-67be13df9a12"/>
+                    propagationPolicy_id="89d322db-9878-420c-b49c-67be13df9a12"
+                    provisions='[{"anyType":"PRINTER","objectClass":"__PRINTER__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"PRINTERNAME","connObjectKey":false,"password":false, [...]
 
   <ExternalResource id="rest-target-resource" connector_id="44c02549-19c3-483c-8025-4919c3283c37"
                     createTraceLevel="ALL" updateTraceLevel="ALL"  deleteTraceLevel="ALL" provisioningTraceLevel="ALL" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    propagationPriority="0" randomPwdIfNotProvided="0"/>
+                    propagationPriority="0" randomPwdIfNotProvided="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"firstname","extAttrName":"firstName","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false [...]
 
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <AccountPolicy_ExternalResource accountPolicy_id="20ab5a8c-4b0c-432c-b957-f7fb9784d9f7" resource_id="resource-testdb"/>
@@ -742,302 +698,17 @@ under the License.
   <SyncopeGroup_ExternalResource group_id="0626100b-a4ba-4e00-9971-86fad52a6216" resource_id="resource-csv"/>
   <SyncopeGroup_ExternalResource group_id="ba9ed509-b1f5-48ab-a334-c8530a6422dc" resource_id="resource-csv"/>
      
-  <Provision ignoreCaseMatch="0" id="209ea85f-f964-49c7-a498-6c9c2baa3bd8" resource_id="ws-target-resource-1" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" provision_id="209ea85f-f964-49c7-a498-6c9c2baa3bd8"/>
-  <MappingItem id="96aad4e0-2678-4903-a52f-0a7d090a2863" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" extAttrName="userId"
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="7f55b09c-b573-41dc-a9eb-ccd80bd3ea7a" extAttrName="email" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               intAttrName="email" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="a9749641-0556-49e2-a519-9bec35a4e06e" extAttrName="surname" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="d118671c-2e3e-4aa3-a3dd-fde2ba4c4ded" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="PROPAGATION"/>
-  <MappingItem id="dca9de4f-9a5a-4280-8e9a-357e321ba7a5" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" 
-               extAttrName="fullname" intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="471f0e2e-2bde-4442-9abf-0effb533f2ee" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="type" intAttrName="ctype" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="72324cda-a66c-4ffe-b6b6-1d9b6cee9bf2" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="name" intAttrName="firstname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="NONE"/>
-  
-  <Provision ignoreCaseMatch="0" id="41a53a00-0b35-4047-831a-d5238f74c7ba" resource_id="ws-target-resource-list-mappings-1" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99" provision_id="41a53a00-0b35-4047-831a-d5238f74c7ba"/>
-  <MappingItem id="6f8d7b42-44f4-4697-aff5-1736c4b01ee4" mapping_id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99"
-               extAttrName="email" intAttrName="email" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="8515e385-3bf1-4928-adc9-489dee65829a" extAttrName="surname"
-               mapping_id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99"
-               intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="09a65250-d9de-44b1-9412-11ed996d356d" resource_id="ws-target-resource-list-mappings-2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="b12c4fad-f0f1-406d-b143-f2d68ed28e3a" provision_id="09a65250-d9de-44b1-9412-11ed996d356d"/>
-  <MappingItem id="55a4cf7f-ac96-4e8b-931c-2d0eab6a6bca" mapping_id="b12c4fad-f0f1-406d-b143-f2d68ed28e3a"
-               extAttrName="userId" intAttrName="userId" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="3d75991b-caee-4993-8e46-afb13d1bfbd4" resource_id="ws-target-resource-2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="240a0291-f89d-4557-a547-2a3b9aad625b" provision_id="3d75991b-caee-4993-8e46-afb13d1bfbd4"/>
-  <MappingItem id="d5c4d467-cd18-4148-8195-015808b4b3e6" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               extAttrName="fullname" intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="370a8673-f3f7-4328-a9ce-acd946f687c5" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-  <MappingItem id="c8d1a47a-1846-47b8-9f68-30aa21e94dcc" extAttrName="type" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="ctype" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="f0a06b24-7d4d-480e-8188-e53045885569" extAttrName="surname" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="surname" mandatoryCondition="type == 'F'"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="adc3c628-27b3-4740-be01-2f83c210ace9" extAttrName="name" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="virtualdata" mandatoryCondition="type == 'F'"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="6972a78b-2570-45d9-bc0b-31d2f2f9c860" extAttrName="fullname" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="cn" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-    
-  <Provision ignoreCaseMatch="0" id="9ebc3237-49fa-4dce-9a4c-3070e931812f" resource_id="ws-target-resource-update" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d" provision_id="9ebc3237-49fa-4dce-9a4c-3070e931812f"/>
-  <MappingItem id="cc973ed6-d031-4790-adab-fc059ac0c818" extAttrName="email" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="email" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="7a72c812-1897-4db0-bed4-4e7e8ea51afe" extAttrName="userId" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="userId" mandatoryCondition="false"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="946a3c7f-6359-4ab7-8a5f-adb08bdb4b5b" extAttrName="test3" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="fullname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-    
-  <Provision ignoreCaseMatch="0" id="8680bc79-dfa1-4719-9886-1d582bf1124f" resource_id="ws-target-resource-nopropagation" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="63ddd4c8-efed-4a22-a4b4-1f4e6f47c8d0" provision_id="8680bc79-dfa1-4719-9886-1d582bf1124f"/>
-  <MappingItem id="ffcfbb5e-7bbd-489a-a69e-2dd84f00731a" mapping_id="63ddd4c8-efed-4a22-a4b4-1f4e6f47c8d0" extAttrName="fullname" 
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="0bfa7c3e-2bb3-43d7-ac0e-d57cff7a18c8" resource_id="ws-target-resource-nopropagation2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="3f636292-6edb-4d20-ab24-fe0c5fc3dec3" provision_id="0bfa7c3e-2bb3-43d7-ac0e-d57cff7a18c8"/>
-  <MappingItem id="e34928b8-ca57-4b6c-81c1-70bc87ff3fdc" mapping_id="3f636292-6edb-4d20-ab24-fe0c5fc3dec3" extAttrName="fullname" 
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="5bd76fec-f8d7-4ab9-acd7-89e099d534e8" resource_id="ws-target-resource-nopropagation3" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c2a0cec1-32c4-4493-8f01-d1176e557fc1" provision_id="5bd76fec-f8d7-4ab9-acd7-89e099d534e8"/>
-  <MappingItem id="f3ba0859-b0f0-44a5-abfd-4a1a5ca29fbf" mapping_id="c2a0cec1-32c4-4493-8f01-d1176e557fc1" extAttrName="fullname"
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="18de6376-7051-4216-96f0-26629076abb9" resource_id="ws-target-resource-nopropagation4" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="906452d9-3eeb-4ef7-ac90-5ffc14513fbf" provision_id="18de6376-7051-4216-96f0-26629076abb9"/>
-  <MappingItem id="118" mapping_id="906452d9-3eeb-4ef7-ac90-5ffc14513fbf"
-               extAttrName="fullname" intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                       
-  <Provision ignoreCaseMatch="0" id="779fefb5-dd25-4078-915d-3c199ee32158" resource_id="resource-testdb" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="cb624b93-874b-40a0-8021-3b8116b781ab" provision_id="779fefb5-dd25-4078-915d-3c199ee32158"/>
-  <MappingItem id="1e0d30cd-2569-4a80-b9dc-af1467bd1c0b" mapping_id="cb624b93-874b-40a0-8021-3b8116b781ab"
-               extAttrName="ID" intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="7fd1a178-77a1-4c4c-aca2-3c3f1834b77b" mapping_id="cb624b93-874b-40a0-8021-3b8116b781ab"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-                     
-  <Provision ignoreCaseMatch="0" id="0359084d-68fe-4bf8-b42b-2ebe4f578ae7" resource_id="resource-testdb2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" provision_id="0359084d-68fe-4bf8-b42b-2ebe4f578ae7"/>
-  <MappingItem id="6d90658a-f470-4450-912d-6fe7d3bcda46" mapping_id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" extAttrName="ID" 
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="2fb9eb01-50df-456e-86c1-b55f68cde2da" mapping_id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" extAttrName="__PASSWORD__" 
-               intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="PROPAGATION"/>
-                         
-  <Provision ignoreCaseMatch="0" id="2adb6537-e207-4d9b-804f-90bf18cd6f48" resource_id="resource-csv" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="csv"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="generic membership"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="minimal group"/>
-  <Mapping id="538c27dc-d260-4c53-9fc8-bf02ee226911" provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48"/>
-  <MappingItem id="517dc983-99a2-43c9-b4b4-78fd838e5ad1" extAttrName="id" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="ba6fb125-466e-4109-8e5d-133936437674" extAttrName="id" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="c426b070-0290-42be-9ee1-4046c7649635" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-  <MappingItem id="20dbe358-5b71-4edd-8670-2bbde982e5c4" extAttrName="name" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="firstname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="4d70850e-9fc5-4e75-83ea-432fe090e1c0" extAttrName="surname" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="surname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="4b2f4292-d8ab-4948-a341-3f8c9e23e72d" extAttrName="email" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="userId" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PULL"/>
-  <MappingItem id="20d6c914-54e7-4968-b1fc-685ae9c2c4a4" extAttrName="email" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="email" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PULL"/>
-  <MappingItem id="09237f39-0d45-4258-a7cc-2400f7536b72" extAttrName="__NAME__" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="csvuserid" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="63151b89-2eb3-4980-a682-0215d54ab4a2" extAttrName="theirgroup" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="groups[root].rderToBePropagated" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-                         
-  <Provision ignoreCaseMatch="0" id="1b53c74e-6a63-49ef-b2f1-96eeb7f1bbb8" resource_id="ws-target-resource-update-resetsynctoken" anyType_id="USER" objectClass="__ACCOUNT__"
-             serializedSyncToken='{"value":null}'/>
-  <Mapping id="23e20ce6-1ff9-495e-aa59-a58e5127a008" provision_id="1b53c74e-6a63-49ef-b2f1-96eeb7f1bbb8"/>
-  <MappingItem id="608f01c5-eb7c-462a-b4d6-b7c3c9632a50" mapping_id="23e20ce6-1ff9-495e-aa59-a58e5127a008"
-               extAttrName="userId" intAttrName="userId" mandatoryCondition="false"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="79ada054-5f8b-4e77-b405-bfec58b06e7b" mapping_id="23e20ce6-1ff9-495e-aa59-a58e5127a008"
-               extAttrName="__PASSWORD__" intAttrName="fullname" mandatoryCondition="false"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-
-  <Provision ignoreCaseMatch="0" id="8b938d63-aa92-448c-89a8-a685fc0a67c8" resource_id="resource-ldap" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Provision_AnyTypeClass provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" anyTypeClass_id="generic membership"/>
-  <Provision_AnyTypeClass provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" anyTypeClass_id="minimal group"/>
-  <Mapping id="ae1c77c3-2f1d-4258-ad06-710bb09041a9" provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8"
-           connObjectLink="&apos;uid=&apos; + username + &apos;,ou=people,o=isp&apos;"/>
-  <MappingItem id="9ff7d686-452c-4cec-a475-c1137c5d88c7" connObjectKey="1" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="cn" intAttrName="username"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="73d97083-cfda-44e6-be62-3f9ac558b5eb" connObjectKey="0" password="1" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="__PASSWORD__" intAttrName="password"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="cf0a222c-36ea-41e6-987c-7908614ccd23" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="sn" intAttrName="surname"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="b3a12364-e471-4e37-83ad-476c33a43617" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="cn" intAttrName="fullname"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="aad2b7d7-3201-4bba-b496-f6587b4b7518" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="mail" intAttrName="email"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="81b83c98-127b-469b-a497-412ba50acbeb" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="title" intAttrName="title"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="318e92a1-3acb-49c5-b2fd-dba819c40ef1" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="postalAddress" intAttrName="postalAddress"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="78fa504f-213c-41ac-a922-7c9f98e5ce11" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="mail" intAttrName="userId"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="af6085cb-d0e8-47c9-b5f9-4b7d491a9750" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="registeredAddress" intAttrName="obscure"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="5bb62bd2-5007-4eb8-b4f9-9df8917dc767" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="jpegPhoto" intAttrName="photo"
-               mandatoryCondition="false" purpose="BOTH"/>
-        
   <SyncopeSchema id="virtualReadOnly"/>
   <VirSchema id="virtualReadOnly" READONLY="1" anyTypeClass_id="minimal user"
-             provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" extAttrName="givenname"/>
-
-  <Provision ignoreCaseMatch="0" id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d" resource_id="resource-ldap" anyType_id="GROUP" objectClass="__GROUP__"/>
-  <Mapping id="128412c8-be4f-4d7b-8bed-5ab89134f718" provision_id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d"
-           connObjectLink="&apos;cn=&apos; + name + &apos;,ou=groups,o=isp&apos;"/>
-  <MappingItem id="a2bf43c8-74cb-4250-92cf-fb8889409ac1"
-               connObjectKey="1" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="cn" intAttrName="name"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="da2a69bc-5ca0-4657-9a18-ec1f8c986046"
-               connObjectKey="0" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="owner" intAttrName="userOwner"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="9dde8bd5-f158-499e-9d81-3d7fcf9ea1e8"
-               connObjectKey="0" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="description" intAttrName="title"
-               mandatoryCondition="false" purpose="BOTH"/>
+             resource_id="resource-ldap" anyType_id="USER" extAttrName="givenname"/>
   
   <SyncopeSchema id="rvirtualdata"/>
   <VirSchema id="rvirtualdata" READONLY="0" anyTypeClass_id="minimal group"
-             provision_id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d" extAttrName="businessCategory"/>
-
-  <Provision ignoreCaseMatch="0" id="46b54e2a-e43e-4cd7-8c13-1af1bd65c3d3" resource_id="resource-db-pull" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="cda910bd-fc28-4f63-890e-66edc62d428b" provision_id="46b54e2a-e43e-4cd7-8c13-1af1bd65c3d3"/>
-  <MappingItem id="1a345706-a498-41bb-a948-820307a4365e" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="EMAIL" intAttrName="email" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="a234bde8-b431-408c-8ec9-c986c5b7f98d" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="SURNAME" intAttrName="fullname" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-  <MappingItem id="51a856de-ae25-41cd-967a-86920c834b70" connObjectKey="1" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="ID" intAttrName="firstname" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="f4e5178e-ef37-4949-933a-7ec7eaea64c6" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="SURNAME" intAttrName="surname" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="3ac0ecaf-d9a1-4fc1-9ae9-84dc34576810" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="USERNAME" intAttrName="username" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="e7215305-93c9-460b-b862-46f7b60de72d" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="EMAIL" intAttrName="userId" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-  <MappingItem id="fb59d169-cf59-43f6-a517-adfd9aacc609" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="MUSTCHANGEPASSWORD" intAttrName="mustChangePassword" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-              
-  <Provision ignoreCaseMatch="0" id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930" resource_id="resource-db-virattr" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="45280585-308f-4571-9788-c7a4734b3614" provision_id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930"/>
-  <MappingItem id="6cb2f9f0-5fb4-4686-a375-31e2c34a6cd8" mapping_id="45280585-308f-4571-9788-c7a4734b3614" connObjectKey="1" password="0"
-               extAttrName="ID" intAttrName="key" 
-               mandatoryCondition="true" purpose="BOTH"/>
-                
+             resource_id="resource-ldap" anyType_id="GROUP" extAttrName="businessCategory"/>
+
   <SyncopeSchema id="virtualdata"/>
   <VirSchema id="virtualdata" READONLY="0" anyTypeClass_id="minimal user"
-             provision_id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930" extAttrName="USERNAME"/>
-  
-  <Provision ignoreCaseMatch="0" id="cfa86cbe-94b6-4712-a40a-a4861be1d425" resource_id="ws-target-resource-timeout" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c71d690a-3dd9-48a5-b76f-32805186c4dc" provision_id="cfa86cbe-94b6-4712-a40a-a4861be1d425"/>
-  <MappingItem id="321bc904-e1fc-4a54-bf7c-74c8cbcc0815" mapping_id="c71d690a-3dd9-48a5-b76f-32805186c4dc" connObjectKey="1" password="0"
-               extAttrName="fullname" intAttrName="fullname"
-               mandatoryCondition="true" purpose="PROPAGATION"/>
-  
-  <Provision ignoreCaseMatch="0" id="ac1659dc-3ea3-45eb-8ae6-626e3d916492" resource_id="ws-target-resource-delete" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="72f590ae-2754-456b-aabb-eda7d8459dd3" provision_id="ac1659dc-3ea3-45eb-8ae6-626e3d916492"/>
-  <MappingItem id="4c98536f-10df-4953-b2df-59d7cd057fd2" mapping_id="72f590ae-2754-456b-aabb-eda7d8459dd3" extAttrName="userId" 
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="f1b55b66-eb13-4a93-a49c-448e93756eb6" resource_id="resource-db-scripted" anyType_id="PRINTER" objectClass="__PRINTER__"/>
-  <Mapping id="16439b5f-50c3-4604-97e9-f4004933abd8" provision_id="f1b55b66-eb13-4a93-a49c-448e93756eb6"/>
-  <MappingItem id="23aa0299-ddbb-4e59-8918-0ab2a32465fa" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="ID" 
-               intAttrName="key" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="3dc96af0-5d0a-4ec1-be84-244716d88401" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="PRINTERNAME" 
-               intAttrName="name" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="f3ef9f8b-e667-4b18-969f-ba98c3d78bc0" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="LOCATION" 
-               intAttrName="location"
-               mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
-    
-  <Provision ignoreCaseMatch="0" id="2e372858-f43c-4e1c-b728-58f43c5e1c23" objectClass="__ACCOUNT__" anyType_id="USER" resource_id="rest-target-resource"/>
-  <Mapping id="e6b64584-94a2-4890-b645-8494a2089011" provision_id="2e372858-f43c-4e1c-b728-58f43c5e1c23"/>
-  <MappingItem id="14726efb-09e1-441e-b26e-fb09e1841eb2" connObjectKey="0"
-               extAttrName="firstName" intAttrName="firstname" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="4cdd1fd5-80cd-4fc1-9d1f-d580cd1fc11e" connObjectKey="1"
-               extAttrName="key" intAttrName="key" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="4d7581b5-fe9b-49e6-b581-b5fe9bf9e60b" connObjectKey="0"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true" password="1" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="98f96cf4-fba2-4c68-b96c-f4fba2fc6834" connObjectKey="0"
-               extAttrName="username" intAttrName="username" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="f3312f8f-1c94-493a-b12f-8f1c94093aa9" connObjectKey="0"
-               extAttrName="email" intAttrName="email" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="ff49e982-fe60-4c1e-89e9-82fe60dc1ef9" connObjectKey="0"
-               extAttrName="surname" intAttrName="surname" mandatoryCondition="true" password="0" PURPOSE="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
+             resource_id="resource-db-virattr" anyType_id="USER" extAttrName="USERNAME"/>
 
   <Implementation id="PullJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
                   body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/>
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index 564c6fe5f5..c0fd4366bb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -54,6 +54,7 @@ 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.DynRealm;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
@@ -61,7 +62,6 @@ 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.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.springframework.transaction.annotation.Propagation;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index bbed01ad3f..bcefd68db7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -53,9 +53,4 @@ public abstract class AbstractDAO<E extends Entity> implements DAO<E> {
     public void detach(final E entity) {
         entityManager().detach(entity);
     }
-
-    @Override
-    public void clear() {
-        entityManager().clear();
-    }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
index fac1e2f951..6d8dad2e0e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPullCorrelationRule.java
@@ -26,13 +26,13 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.policy.DefaultPullCorrelationRuleConf;
 import org.apache.syncope.common.lib.policy.PullCorrelationRuleConf;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule;
 import org.apache.syncope.core.persistence.api.dao.PullCorrelationRuleConfClass;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.resource.Item;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 
@@ -61,8 +61,8 @@ public class DefaultPullCorrelationRule implements PullCorrelationRule {
 
         conf.getSchemas().forEach(schema -> {
             Item item = mappingItems.get(schema);
-            Attribute attr = Optional.ofNullable(item)
-                .map(item1 -> syncDelta.getObject().getAttributeByName(item1.getExtAttrName())).orElse(null);
+            Attribute attr = Optional.ofNullable(item).
+                    map(item1 -> syncDelta.getObject().getAttributeByName(item1.getExtAttrName())).orElse(null);
             if (attr == null) {
                 throw new IllegalArgumentException(
                         "Connector object does not contains the attributes to perform the search: " + schema);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPushCorrelationRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPushCorrelationRule.java
index fc2dc9f50e..836f4a1cc3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPushCorrelationRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPushCorrelationRule.java
@@ -28,11 +28,12 @@ import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf;
 import org.apache.syncope.common.lib.policy.PushCorrelationRuleConf;
 import org.apache.syncope.common.lib.search.ConnObjectTOFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.dao.PushCorrelationRule;
 import org.apache.syncope.core.persistence.api.dao.PushCorrelationRuleConfClass;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.provisioning.api.AccountGetter;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.PlainAttrGetter;
@@ -69,13 +70,14 @@ public class DefaultPushCorrelationRule implements PushCorrelationRule {
     }
 
     @Override
-    public Filter getFilter(final Any<?> any, final Provision provision) {
+    public Filter getFilter(final Any<?> any, final ExternalResource resource, final Provision provision) {
         List<Filter> filters = new ArrayList<>();
 
         provision.getMapping().getItems().stream().filter(
                 item -> conf.getSchemas().contains(item.getIntAttrName()) && item.getPurpose() != MappingPurpose.NONE).
                 forEach(item -> {
                     Pair<String, Attribute> attr = mappingManager.prepareAttr(
+                            resource,
                             provision,
                             item,
                             any,
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index de1fab99c5..48d50dfff1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -46,6 +46,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Membership;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Relationship;
@@ -53,7 +54,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 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.user.URelationship;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 5212d762c6..531443decc 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
@@ -33,7 +34,6 @@ import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
 
 public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass> implements AnyTypeClassDAO {
@@ -126,10 +126,9 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass> implements Any
         }
 
         for (Provision provision : resourceDAO.findProvisionsByAuxClass(anyTypeClass)) {
-            provision.getAuxClasses().remove(anyTypeClass);
+            provision.getAuxClasses().remove(anyTypeClass.getKey());
         }
 
         entityManager().remove(anyTypeClass);
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrRepoDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrRepoDAO.java
index 099497732b..2a80b54a70 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrRepoDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrRepoDAO.java
@@ -43,6 +43,7 @@ public class JPAAttrRepoDAO extends AbstractDAO<AttrRepo> implements AttrRepoDAO
 
     @Override
     public AttrRepo save(final AttrRepo attrRepo) {
+        ((JPAAttrRepo) attrRepo).list2json();
         return entityManager().merge(attrRepo);
     }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthModuleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthModuleDAO.java
index df8e88a6f9..b216861889 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthModuleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuthModuleDAO.java
@@ -52,6 +52,7 @@ public class JPAAuthModuleDAO extends AbstractDAO<AuthModule> implements AuthMod
 
     @Override
     public AuthModule save(final AuthModule authModule) {
+        ((JPAAuthModule) authModule).list2json();
         return entityManager().merge(authModule);
     }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 30baa5708e..ce892eee36 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -85,6 +85,7 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance> implements Con
 
     @Override
     public ConnInstance save(final ConnInstance connector) {
+        ((JPAConnInstance) connector).list2json();
         return entityManager().merge(connector);
     }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 2a321d754b..43f2c402f0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -19,11 +19,12 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -35,7 +36,7 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
@@ -43,16 +44,11 @@ import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implements ExternalResourceDAO {
 
@@ -124,22 +120,19 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
 
     @Override
     public List<Provision> findProvisionsByAuxClass(final AnyTypeClass anyTypeClass) {
-        TypedQuery<Provision> query = entityManager().createQuery(
-                "SELECT e FROM " + JPAProvision.class.getSimpleName()
-                + " e WHERE :anyTypeClass MEMBER OF e.auxClasses", Provision.class);
-        query.setParameter("anyTypeClass", anyTypeClass);
-
-        return query.getResultList();
+        return findAll().stream().
+                flatMap(resource -> resource.getProvisions().stream()).
+                filter(provision -> provision.getAuxClasses().contains(anyTypeClass.getKey())).
+                collect(Collectors.toList());
     }
 
     @Override
-    public List<MappingItem> findByTransformer(final Implementation transformer) {
-        TypedQuery<MappingItem> query = entityManager().createQuery(
-                "SELECT e FROM " + JPAMappingItem.class.getSimpleName()
-                + " e WHERE :transformer MEMBER OF e.transformers", MappingItem.class);
-        query.setParameter("transformer", transformer);
-
-        return query.getResultList();
+    public boolean anyItemHaving(final Implementation transformer) {
+        return findAll().stream().
+                flatMap(resource -> resource.getProvisions().stream()).
+                flatMap(provision -> provision.getMapping().getItems().stream()).
+                filter(item -> item.getTransformers().contains(transformer.getKey())).
+                count() > 0;
     }
 
     @Override
@@ -184,7 +177,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
     @Override
     public List<ExternalResource> findAll() {
         Set<String> authRealms = AuthContextUtils.getAuthorizations().get(IdMEntitlement.RESOURCE_LIST);
-        if (authRealms == null || authRealms.isEmpty()) {
+        if (CollectionUtils.isEmpty(authRealms)) {
             return List.of();
         }
 
@@ -200,29 +193,24 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public ExternalResource save(final ExternalResource resource) {
+        ((JPAExternalResource) resource).list2json();
         return entityManager().merge(resource);
     }
 
     @Override
-    @SuppressWarnings("unchecked")
     public void deleteMapping(final String intAttrName) {
-        TypedQuery<MappingItem> query = entityManager().createQuery(
-                "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
-                + " m WHERE m.intAttrName=:intAttrName", MappingItem.class);
-        query.setParameter("intAttrName", intAttrName);
-
-        query.getResultList().stream().
-                map(Entity::getKey).
-                map(itemKey -> entityManager().find(JPAMappingItem.class, itemKey)).filter(Objects::nonNull).
-                forEach(item -> {
-                    item.getMapping().getItems().remove(item);
-                    item.setMapping(null);
-                    entityManager().remove(item);
-                });
-
-        // Make empty query cache for *MappingItem and related *Mapping
-        entityManager().getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
-        entityManager().getEntityManagerFactory().getCache().evict(JPAMapping.class);
+        findAll().forEach(resource -> {
+            AtomicBoolean removed = new AtomicBoolean(false);
+
+            resource.getProvisions().forEach(provision -> removed.set(
+                    removed.get()
+                    || (provision.getMapping() != null
+                    && provision.getMapping().getItems().removeIf(item -> intAttrName.equals(item.getIntAttrName())))));
+
+            if (removed.get()) {
+                entityManager().merge(resource);
+            }
+        });
     }
 
     @Override
@@ -251,20 +239,10 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implem
         policyDAO.findByResource(resource).
                 forEach(policy -> policy.getResources().remove(resource));
 
-        resource.getProvisions().stream().
-                peek(provision -> {
-                    provision.setUidOnCreate(null);
-                    if (provision.getMapping() != null) {
-                        provision.getMapping().getItems().forEach(item -> item.setMapping(null));
-                        provision.getMapping().getItems().clear();
-                    }
-                    provision.setMapping(null);
-                    provision.setResource(null);
-                }).
-                forEach(provision -> virSchemaDAO.findByProvision(provision).
-                forEach(schema -> virSchemaDAO.delete(schema.getKey())));
-
-        if (resource.getConnector() != null && resource.getConnector().getResources() != null
+        virSchemaDAO.find(resource).forEach(virSchemaDAO::delete);
+
+        if (resource.getConnector() != null
+                && resource.getConnector().getResources() != null
                 && !resource.getConnector().getResources().isEmpty()) {
 
             resource.getConnector().getResources().remove(resource);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
index d4d56947f1..32ad3121d5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAImplementationDAO.java
@@ -69,5 +69,4 @@ public class JPAImplementationDAO extends AbstractDAO<Implementation> implements
         entityManager().remove(implementation);
         ImplementationManager.purge(key);
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
index b3c386e723..6e6c3a97bb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
@@ -26,6 +26,7 @@ import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
@@ -36,7 +37,6 @@ import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.policy.AbstractPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccessPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
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 5e7f1a2704..9affc78f08 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
@@ -31,6 +31,7 @@ import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
@@ -41,7 +42,6 @@ import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.ProvisioningPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 import org.springframework.transaction.annotation.Transactional;
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index 9bff44b2ef..6b34d7f7a6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -38,9 +38,9 @@ import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 8235a98479..aca6eee89d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -50,6 +50,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Membership;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
@@ -58,7 +59,6 @@ import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index d0b279d306..9452c685e5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -18,26 +18,18 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
-import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
 import org.apache.syncope.core.persistence.jpa.entity.JPAVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
 
 public class JPAVirSchemaDAO extends AbstractDAO<VirSchema> implements VirSchemaDAO {
 
@@ -68,35 +60,31 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema> implements VirSchema
     }
 
     @Override
-    public List<VirSchema> findByProvision(final Provision provision) {
+    public List<String> find(final ExternalResource resource) {
         Query query = entityManager().createNativeQuery(
-                "SELECT t0.id FROM VirSchema t0 "
-                + "LEFT OUTER JOIN " + JPAAnyTypeClass.TABLE + " t1 ON t0.ANYTYPECLASS_ID = t1.id "
-                + "LEFT OUTER JOIN " + JPAProvision.TABLE + " t2 ON t0.PROVISION_ID = t2.id "
-                + "LEFT OUTER JOIN " + JPAAnyType.TABLE + " t3 ON t2.ANYTYPE_ID = t3.id "
-                + "LEFT OUTER JOIN " + JPAMapping.TABLE + " t4 ON t2.id = t4.PROVISION_ID "
-                + "LEFT OUTER JOIN " + JPAExternalResource.TABLE + " t5 ON t2.RESOURCE_ID = t5.id "
-                + "LEFT OUTER JOIN " + JPAAccountPolicy.TABLE + " t6 ON t5.ACCOUNTPOLICY_ID = t6.id "
-                + "LEFT OUTER JOIN " + JPAConnInstance.TABLE + " t7 ON t5.CONNECTOR_ID = t7.id "
-                + "LEFT OUTER JOIN " + JPAPasswordPolicy.TABLE + " t8 ON t5.PASSWORDPOLICY_ID = t8.id "
-                + "LEFT OUTER JOIN " + JPAPullPolicy.TABLE + " t9 ON t5.PULLPOLICY_ID = t9.id "
-                + "WHERE t0.PROVISION_ID = ?1");
-        query.setParameter(1, provision.getKey());
-
-        List<VirSchema> result = new ArrayList<>();
-        for (Object key : query.getResultList()) {
-            String actualKey = key instanceof Object[]
-                    ? (String) ((Object[]) key)[0]
-                    : ((String) key);
-
-            VirSchema virSchema = find(actualKey);
-            if (virSchema == null) {
-                LOG.error("Could not find schema with id {}, even though returned by the native query", actualKey);
-            } else if (!result.contains(virSchema)) {
-                result.add(virSchema);
-            }
-        }
-        return result;
+                "SELECT id FROM " + JPAVirSchema.TABLE + " e WHERE e.resource_id=?");
+        query.setParameter(1, resource.getKey());
+
+        @SuppressWarnings("unchecked")
+        List<Object> results = query.getResultList();
+        return results.stream().
+                map(Object::toString).
+                collect(Collectors.toList());
+    }
+
+    @Override
+    public List<VirSchema> find(final String resource, final String anyType) {
+        Query query = entityManager().createNativeQuery(
+                "SELECT id FROM " + JPAVirSchema.TABLE + " e WHERE e.resource_id=? AND e.anyType_id=?");
+        query.setParameter(1, resource);
+        query.setParameter(2, anyType);
+
+        @SuppressWarnings("unchecked")
+        List<Object> results = query.getResultList();
+        return results.stream().
+                map(row -> find(row.toString())).
+                filter(Objects::nonNull).
+                collect(Collectors.toList());
     }
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnyTemplate.java
similarity index 92%
rename from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnyTemplate.java
index 58c18abb8c..9eba1df352 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnyTemplate.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.persistence.jpa.entity.resource;
+package org.apache.syncope.core.persistence.jpa.entity;
 
 import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
@@ -25,8 +25,6 @@ import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
index 05ecf6b0cd..a146c6bc4b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
@@ -24,7 +24,6 @@ import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
 
 @Entity
 @Table(name = JPAAnyTemplateRealm.TABLE, uniqueConstraints =
@@ -48,5 +47,4 @@ public class JPAAnyTemplateRealm extends AbstractAnyTemplate implements AnyTempl
         checkType(realm, JPARealm.class);
         this.realm = (JPARealm) realm;
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
index 95e8ff89f6..ae37005b57 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -49,6 +49,7 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
@@ -61,7 +62,6 @@ import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue;
 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.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index a12f5d94e7..2b0b1d8d56 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -25,17 +26,17 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import javax.persistence.CascadeType;
-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.Lob;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.lang3.StringUtils;
@@ -43,9 +44,8 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 
@@ -93,16 +93,10 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
     @NotNull
     private String version;
 
-    /**
-     * The set of capabilities supported by this connector instance.
-     */
-    @ElementCollection(fetch = FetchType.EAGER)
-    @Enumerated(EnumType.STRING)
-    @Column(name = "capability")
-    @CollectionTable(name = "ConnInstance_capabilities",
-            joinColumns =
-            @JoinColumn(name = "connInstance_id", referencedColumnName = "id"))
-    private Set<ConnectorCapability> capabilities = new HashSet<>();
+    @Lob
+    private String capabilities;
+
+    private final Set<ConnectorCapability> capabilitiesSet = new HashSet<>();
 
     /**
      * The main configuration for the connector instance. This is directly implemented by the Configuration bean class
@@ -220,7 +214,7 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
 
     @Override
     public Set<ConnectorCapability> getCapabilities() {
-        return capabilities;
+        return capabilitiesSet;
     }
 
     @Override
@@ -246,4 +240,32 @@ public class JPAConnInstance extends AbstractGeneratedKeyEntity implements ConnI
         checkType(poolConf, JPAConnPoolConf.class);
         this.poolConf = (JPAConnPoolConf) poolConf;
     }
+
+    protected void json2list(final boolean clearFirst) {
+        if (clearFirst) {
+            getCapabilities().clear();
+        }
+        if (capabilities != null) {
+            getCapabilities().addAll(
+                    POJOHelper.deserialize(capabilities, new TypeReference<Set<ConnectorCapability>>() {
+                    }));
+        }
+    }
+
+    @PostLoad
+    public void postLoad() {
+        json2list(false);
+    }
+
+    @PostPersist
+    @PostUpdate
+    public void postSave() {
+        json2list(true);
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void list2json() {
+        capabilities = POJOHelper.serialize(getCapabilities());
+    }
 }
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 4791df4944..43a46bdc91 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
@@ -35,6 +35,7 @@ import org.apache.syncope.core.persistence.api.entity.DynRealm;
 import org.apache.syncope.core.persistence.api.entity.DynRealmMembership;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.FIQLQuery;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.MailTemplate;
@@ -52,9 +53,7 @@ import org.apache.syncope.core.persistence.api.entity.SRARoute;
 import org.apache.syncope.core.persistence.api.entity.SchemaLabel;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.am.AttrRepo;
-import org.apache.syncope.core.persistence.api.entity.am.AttrRepoItem;
 import org.apache.syncope.core.persistence.api.entity.am.AuthModule;
-import org.apache.syncope.core.persistence.api.entity.am.AuthModuleItem;
 import org.apache.syncope.core.persistence.api.entity.am.AuthProfile;
 import org.apache.syncope.core.persistence.api.entity.am.CASSPClientApp;
 import org.apache.syncope.core.persistence.api.entity.am.OIDCJWKS;
@@ -85,12 +84,6 @@ import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRule
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-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.task.AnyTemplatePullTask;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -114,9 +107,7 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO;
 import org.apache.syncope.core.persistence.jpa.entity.am.JPAAttrRepo;
-import org.apache.syncope.core.persistence.jpa.entity.am.JPAAttrRepoItem;
 import org.apache.syncope.core.persistence.jpa.entity.am.JPAAuthModule;
-import org.apache.syncope.core.persistence.jpa.entity.am.JPAAuthModuleItem;
 import org.apache.syncope.core.persistence.jpa.entity.am.JPAAuthProfile;
 import org.apache.syncope.core.persistence.jpa.entity.am.JPACASSPClientApp;
 import org.apache.syncope.core.persistence.jpa.entity.am.JPAOIDCJWKS;
@@ -147,12 +138,6 @@ import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullCorrelationR
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPullPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnit;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnitItem;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplatePullTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
@@ -241,14 +226,10 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPAMailTemplate();
         } else if (reference.equals(Notification.class)) {
             result = (E) new JPANotification();
-        } else if (reference.equals(ExternalResource.class)) {
-            result = (E) new JPAExternalResource();
-        } else if (reference.equals(Provision.class)) {
-            result = (E) new JPAProvision();
-        } else if (reference.equals(OrgUnit.class)) {
-            result = (E) new JPAOrgUnit();
         } else if (reference.equals(ConnInstance.class)) {
             result = (E) new JPAConnInstance();
+        } else if (reference.equals(ExternalResource.class)) {
+            result = (E) new JPAExternalResource();
         } else if (reference.equals(SchemaLabel.class)) {
             result = (E) new JPASchemaLabel();
         } else if (reference.equals(PlainSchema.class)) {
@@ -275,12 +256,6 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPADerSchema();
         } else if (reference.equals(VirSchema.class)) {
             result = (E) new JPAVirSchema();
-        } else if (reference.equals(Mapping.class)) {
-            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)) {
@@ -335,12 +310,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (E) new JPASRARoute();
         } else if (reference.equals(AuthModule.class)) {
             result = (E) new JPAAuthModule();
-        } else if (reference.equals(AuthModuleItem.class)) {
-            result = (E) new JPAAuthModuleItem();
         } else if (reference.equals(AttrRepo.class)) {
             result = (E) new JPAAttrRepo();
-        } else if (reference.equals(AttrRepoItem.class)) {
-            result = (E) new JPAAttrRepoItem();
         } else if (reference.equals(AuthPolicy.class)) {
             result = (E) new JPAAuthPolicy();
         } else if (reference.equals(AccessPolicy.class)) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
similarity index 82%
rename from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
index 816a5afe61..3ecabb3837 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
@@ -16,17 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.persistence.jpa.entity.resource;
+package org.apache.syncope.core.persistence.jpa.entity;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import javax.persistence.Cacheable;
 import javax.persistence.CascadeType;
-import javax.persistence.CollectionTable;
-import javax.persistence.Column;
-import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
@@ -36,30 +35,30 @@ import javax.persistence.JoinTable;
 import javax.persistence.Lob;
 import javax.persistence.ManyToMany;
 import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
 import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.persistence.UniqueConstraint;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.OrgUnit;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.common.lib.types.IdMImplementationType;
 import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-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.persistence.jpa.entity.AbstractProvidedKeyEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
-import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPropagationPolicy;
@@ -75,6 +74,7 @@ import org.identityconnectors.framework.common.objects.ObjectClass;
 @Entity
 @Table(name = JPAExternalResource.TABLE)
 @ExternalResourceCheck
+@Cacheable
 public class JPAExternalResource extends AbstractProvidedKeyEntity implements ExternalResource {
 
     private static final long serialVersionUID = -6937712883512073278L;
@@ -93,12 +93,6 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
     private JPAConnInstance connector;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "resource")
-    private List<JPAProvision> provisions = new ArrayList<>();
-
-    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "resource")
-    private JPAOrgUnit orgUnit;
-
     /**
      * Priority index for propagation ordering.
      */
@@ -145,7 +139,7 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     private JPAImplementation provisionSorter;
 
     /**
-     * Configuration properties that are overridden from the connector instance.
+     * Configuration properties that are override from the connector instance.
      */
     @Lob
     private String jsonConf;
@@ -153,13 +147,20 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     @NotNull
     private Boolean overrideCapabilities = false;
 
-    @ElementCollection(fetch = FetchType.EAGER)
-    @Enumerated(EnumType.STRING)
-    @Column(name = "capabilityOverride")
-    @CollectionTable(name = "ExternalResource_capOverride",
-            joinColumns =
-            @JoinColumn(name = "resource_id", referencedColumnName = "id"))
-    private Set<ConnectorCapability> capabilitiesOverride = new HashSet<>();
+    @Lob
+    private String capabilitiesOverride;
+
+    @Transient
+    private final Set<ConnectorCapability> capabilitiesOverrideSet = new HashSet<>();
+
+    @Lob
+    private String provisions;
+
+    @Transient
+    private final List<Provision> provisionList = new ArrayList<>();
+
+    @Lob
+    private String orgUnit;
 
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(name = TABLE + "PropAction",
@@ -193,43 +194,30 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     }
 
     @Override
-    public boolean add(final Provision provision) {
-        checkType(provision, JPAProvision.class);
-        return this.provisions.add((JPAProvision) provision);
-    }
-
-    @Override
-    public Optional<? extends Provision> getProvision(final String anyType) {
-        return getProvisions().stream().
-                filter(provision -> provision.getAnyType().getKey().equals(anyType)).findFirst();
-    }
-
-    @Override
-    public Optional<? extends Provision> getProvision(final AnyType anyType) {
+    public Optional<Provision> getProvision(final String anyType) {
         return getProvisions().stream().
                 filter(provision -> provision.getAnyType().equals(anyType)).findFirst();
     }
 
     @Override
-    public Optional<? extends Provision> getProvision(final ObjectClass objectClass) {
+    public Optional<Provision> getProvision(final ObjectClass objectClass) {
         return getProvisions().stream().
-                filter(provision -> provision.getObjectClass().equals(objectClass)).findFirst();
+                filter(provision -> provision.getObjectClass().equals(objectClass.getObjectClassValue())).findFirst();
     }
 
     @Override
-    public List<? extends Provision> getProvisions() {
-        return provisions == null ? List.of() : provisions;
+    public List<Provision> getProvisions() {
+        return provisionList;
     }
 
     @Override
     public OrgUnit getOrgUnit() {
-        return orgUnit;
+        return Optional.ofNullable(orgUnit).map(ou -> POJOHelper.deserialize(ou, OrgUnit.class)).orElse(null);
     }
 
     @Override
     public void setOrgUnit(final OrgUnit orgUnit) {
-        checkType(orgUnit, JPAOrgUnit.class);
-        this.orgUnit = (JPAOrgUnit) orgUnit;
+        this.orgUnit = orgUnit == null ? null : POJOHelper.serialize(orgUnit);
     }
 
     @Override
@@ -387,7 +375,7 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
 
     @Override
     public Set<ConnectorCapability> getCapabilitiesOverride() {
-        return capabilitiesOverride;
+        return capabilitiesOverrideSet;
     }
 
     @Override
@@ -402,4 +390,39 @@ public class JPAExternalResource extends AbstractProvidedKeyEntity implements Ex
     public List<? extends Implementation> getPropagationActions() {
         return propagationActions;
     }
+
+    protected void json2list(final boolean clearFirst) {
+        if (clearFirst) {
+            getCapabilitiesOverride().clear();
+            getProvisions().clear();
+        }
+        if (capabilitiesOverride != null) {
+            getCapabilitiesOverride().addAll(
+                    POJOHelper.deserialize(capabilitiesOverride, new TypeReference<Set<ConnectorCapability>>() {
+                    }));
+        }
+        if (provisions != null) {
+            getProvisions().addAll(
+                    POJOHelper.deserialize(provisions, new TypeReference<List<Provision>>() {
+                    }));
+        }
+    }
+
+    @PostLoad
+    public void postLoad() {
+        json2list(false);
+    }
+
+    @PostPersist
+    @PostUpdate
+    public void postSave() {
+        json2list(true);
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void list2json() {
+        capabilitiesOverride = POJOHelper.serialize(getCapabilitiesOverride());
+        provisions = POJOHelper.serialize(getProvisions());
+    }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
index abe881c4a5..43b30c2e88 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java
@@ -39,6 +39,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
@@ -46,13 +47,11 @@ import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AttrReleasePolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccessPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAttrReleasePolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAAuthPolicy;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPasswordPolicy;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.RealmCheck;
 
 @Entity
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
index 2d79ea3e7a..905aee8ac8 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
@@ -26,12 +26,10 @@ import javax.persistence.PrimaryKeyJoinColumn;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.LinkingMappingItem;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision;
 
 @Entity
 @Table(name = JPAVirSchema.TABLE)
@@ -49,7 +47,11 @@ public class JPAVirSchema extends AbstractSchema implements VirSchema {
 
     @NotNull
     @ManyToOne
-    private JPAProvision provision;
+    private JPAExternalResource resource;
+
+    @NotNull
+    @ManyToOne
+    private JPAAnyType anyType;
 
     @NotNull
     private String extAttrName;
@@ -96,29 +98,34 @@ public class JPAVirSchema extends AbstractSchema implements VirSchema {
     }
 
     @Override
-    public Provision getProvision() {
-        return provision;
+    public ExternalResource getResource() {
+        return resource;
     }
 
     @Override
-    public void setProvision(final Provision provision) {
-        checkType(provision, JPAProvision.class);
-        this.provision = (JPAProvision) provision;
+    public void setResource(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        this.resource = (JPAExternalResource) resource;
     }
 
     @Override
-    public String getExtAttrName() {
-        return extAttrName;
+    public AnyType getAnyType() {
+        return anyType;
     }
 
     @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
     }
 
     @Override
-    public MappingItem asLinkingMappingItem() {
-        return new LinkingMappingItem(this);
+    public String getExtAttrName() {
+        return extAttrName;
     }
 
+    @Override
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
index 23d8502cb7..9f452b69fc 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepo.java
@@ -18,23 +18,27 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.am;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
-import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
-import javax.persistence.FetchType;
 import javax.persistence.Lob;
-import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
 import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.attr.AttrRepoConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AttrRepoState;
 import org.apache.syncope.core.persistence.api.entity.am.AttrRepo;
-import org.apache.syncope.core.persistence.api.entity.am.AttrRepoItem;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 
@@ -55,8 +59,11 @@ public class JPAAttrRepo extends AbstractProvidedKeyEntity implements AttrRepo {
     @NotNull
     private Integer attrRepoOrder = 0;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "attrRepo")
-    private List<JPAAttrRepoItem> items = new ArrayList<>();
+    @Lob
+    private String items;
+
+    @Transient
+    private final List<Item> itemList = new ArrayList<>();
 
     @Lob
     private String jsonConf;
@@ -92,14 +99,8 @@ public class JPAAttrRepo extends AbstractProvidedKeyEntity implements AttrRepo {
     }
 
     @Override
-    public List<? extends AttrRepoItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean add(final AttrRepoItem item) {
-        checkType(item, JPAAttrRepoItem.class);
-        return items.contains((JPAAttrRepoItem) item) || items.add((JPAAttrRepoItem) item);
+    public List<Item> getItems() {
+        return itemList;
     }
 
     @Override
@@ -116,4 +117,32 @@ public class JPAAttrRepo extends AbstractProvidedKeyEntity implements AttrRepo {
     public void setConf(final AttrRepoConf conf) {
         jsonConf = POJOHelper.serialize(conf);
     }
+
+    protected void json2list(final boolean clearFirst) {
+        if (clearFirst) {
+            getItems().clear();
+        }
+        if (items != null) {
+            getItems().addAll(
+                    POJOHelper.deserialize(items, new TypeReference<List<Item>>() {
+                    }));
+        }
+    }
+
+    @PostLoad
+    public void postLoad() {
+        json2list(false);
+    }
+
+    @PostPersist
+    @PostUpdate
+    public void postSave() {
+        json2list(true);
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void list2json() {
+        items = POJOHelper.serialize(getItems());
+    }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepoItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepoItem.java
deleted file mode 100644
index c6d9afa2eb..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAttrRepoItem.java
+++ /dev/null
@@ -1,94 +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.jpa.entity.am;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.common.lib.types.IdRepoImplementationType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.am.AttrRepo;
-import org.apache.syncope.core.persistence.api.entity.am.AttrRepoItem;
-import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
-import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem;
-
-@Entity
-@Table(name = JPAAttrRepoItem.TABLE)
-@Cacheable
-public class JPAAttrRepoItem extends AbstractItem implements AttrRepoItem {
-
-    public static final String TABLE = "AttrRepoItem";
-
-    private static final long serialVersionUID = 3165440920144995781L;
-
-    @ManyToOne
-    private JPAAttrRepo attrRepo;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name = TABLE + "Transformer",
-            joinColumns =
-            @JoinColumn(name = "item_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "implementation_id"),
-            uniqueConstraints =
-            @UniqueConstraint(columnNames = { "item_id", "implementation_id" }))
-    private final List<JPAImplementation> transformers = new ArrayList<>();
-
-    public JPAAttrRepoItem() {
-        super.setPurpose(MappingPurpose.NONE);
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        // cannot be changed
-    }
-
-    @Override
-    public AttrRepo getAttrRepo() {
-        return attrRepo;
-    }
-
-    @Override
-    public void setAttrRepo(final AttrRepo attrRepo) {
-        checkType(attrRepo, JPAAttrRepo.class);
-        this.attrRepo = (JPAAttrRepo) attrRepo;
-    }
-
-    @Override
-    public boolean add(final Implementation transformer) {
-        checkType(transformer, JPAImplementation.class);
-        checkImplementationType(transformer, IdRepoImplementationType.ITEM_TRANSFORMER);
-        return transformers.contains((JPAImplementation) transformer)
-                || this.transformers.add((JPAImplementation) transformer);
-    }
-
-    @Override
-    public List<? extends Implementation> getTransformers() {
-        return transformers;
-    }
-}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
index 69f19ac1ca..527fe81de6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModule.java
@@ -18,23 +18,27 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.am;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
-import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
-import javax.persistence.FetchType;
 import javax.persistence.Lob;
-import javax.persistence.OneToMany;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
 import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.auth.AuthModuleConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AuthModuleState;
 import org.apache.syncope.core.persistence.api.entity.am.AuthModule;
-import org.apache.syncope.core.persistence.api.entity.am.AuthModuleItem;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 
@@ -55,8 +59,11 @@ public class JPAAuthModule extends AbstractProvidedKeyEntity implements AuthModu
     @NotNull
     private Integer authModuleOrder = 0;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "authModule")
-    private List<JPAAuthModuleItem> items = new ArrayList<>();
+    @Lob
+    private String items;
+
+    @Transient
+    private final List<Item> itemList = new ArrayList<>();
 
     @Lob
     private String jsonConf;
@@ -92,14 +99,8 @@ public class JPAAuthModule extends AbstractProvidedKeyEntity implements AuthModu
     }
 
     @Override
-    public List<? extends AuthModuleItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean add(final AuthModuleItem item) {
-        checkType(item, JPAAuthModuleItem.class);
-        return items.contains((JPAAuthModuleItem) item) || items.add((JPAAuthModuleItem) item);
+    public List<Item> getItems() {
+        return itemList;
     }
 
     @Override
@@ -116,4 +117,33 @@ public class JPAAuthModule extends AbstractProvidedKeyEntity implements AuthModu
     public void setConf(final AuthModuleConf conf) {
         jsonConf = POJOHelper.serialize(conf);
     }
+
+    protected void json2list(final boolean clearFirst) {
+        if (clearFirst) {
+            getItems().clear();
+        }
+        if (items != null) {
+            getItems().addAll(
+                    POJOHelper.deserialize(items, new TypeReference<List<Item>>() {
+                    }));
+        }
+    }
+
+    @PostLoad
+    public void postLoad() {
+        json2list(false);
+    }
+
+    @PostPersist
+    @PostUpdate
+    public void postSave() {
+        json2list(true);
+    }
+
+    @PrePersist
+    @PreUpdate
+    public void list2json() {
+        items = POJOHelper.serialize(getItems());
+    }
+
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModuleItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModuleItem.java
deleted file mode 100644
index c2c6ba76d7..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAAuthModuleItem.java
+++ /dev/null
@@ -1,94 +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.jpa.entity.am;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.common.lib.types.IdRepoImplementationType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.am.AuthModule;
-import org.apache.syncope.core.persistence.api.entity.am.AuthModuleItem;
-import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
-import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem;
-
-@Entity
-@Table(name = JPAAuthModuleItem.TABLE)
-@Cacheable
-public class JPAAuthModuleItem extends AbstractItem implements AuthModuleItem {
-
-    public static final String TABLE = "AuthModuleItem";
-
-    private static final long serialVersionUID = 3165440920144995781L;
-
-    @ManyToOne
-    private JPAAuthModule authModule;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name = TABLE + "Transformer",
-            joinColumns =
-            @JoinColumn(name = "item_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "implementation_id"),
-            uniqueConstraints =
-            @UniqueConstraint(columnNames = { "item_id", "implementation_id" }))
-    private final List<JPAImplementation> transformers = new ArrayList<>();
-
-    public JPAAuthModuleItem() {
-        super.setPurpose(MappingPurpose.NONE);
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        // cannot be changed
-    }
-
-    @Override
-    public AuthModule getAuthModule() {
-        return authModule;
-    }
-
-    @Override
-    public void setAuthModule(final AuthModule authModule) {
-        checkType(authModule, JPAAuthModule.class);
-        this.authModule = (JPAAuthModule) authModule;
-    }
-
-    @Override
-    public boolean add(final Implementation transformer) {
-        checkType(transformer, JPAImplementation.class);
-        checkImplementationType(transformer, IdRepoImplementationType.ITEM_TRANSFORMER);
-        return transformers.contains((JPAImplementation) transformer)
-                || this.transformers.add((JPAImplementation) transformer);
-    }
-
-    @Override
-    public List<? extends Implementation> getTransformers() {
-        return transformers;
-    }
-}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
index 91af63ac35..8a3d4b40ef 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -37,16 +37,16 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractGroupableRelatable;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.AnyObjectCheck;
 
 @Entity
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index 36ee866288..474bbea1bc 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -38,17 +38,17 @@ import javax.validation.constraints.NotNull;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractAny;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.persistence.jpa.validation.entity.GroupCheck;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
index f9c43026a5..a62aeb92d1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
@@ -31,11 +31,11 @@ import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPAImplementation;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @Entity
 @Table(name = JPAAccountPolicy.TABLE)
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
index d8b90101c3..abdf6c9cea 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPullPolicy.java
@@ -26,7 +26,6 @@ import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
 
@@ -48,9 +47,9 @@ public class JPAPullPolicy extends AbstractProvisioningPolicy implements PullPol
     }
 
     @Override
-    public Optional<? extends PullCorrelationRuleEntity> getCorrelationRule(final AnyType anyType) {
+    public Optional<? extends PullCorrelationRuleEntity> getCorrelationRule(final String anyType) {
         return correlationRules.stream().
-                filter(rule -> anyType != null && anyType.equals(rule.getAnyType())).findFirst();
+                filter(rule -> anyType != null && anyType.equals(rule.getAnyType().getKey())).findFirst();
     }
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
index 9caded4328..ea809985a7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
@@ -26,7 +26,6 @@ import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
 
@@ -48,9 +47,9 @@ public class JPAPushPolicy extends AbstractProvisioningPolicy implements PushPol
     }
 
     @Override
-    public Optional<? extends PushCorrelationRuleEntity> getCorrelationRule(final AnyType anyType) {
+    public Optional<? extends PushCorrelationRuleEntity> getCorrelationRule(final String anyType) {
         return correlationRules.stream().
-                filter(rule -> anyType != null && anyType.equals(rule.getAnyType())).findFirst();
+                filter(rule -> anyType != null && anyType.equals(rule.getAnyType().getKey())).findFirst();
     }
 
     @Override
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
deleted file mode 100644
index f252dd3d7e..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractItem.java
+++ /dev/null
@@ -1,158 +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.jpa.entity.resource;
-
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.MappedSuperclass;
-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 = Boolean.FALSE.toString();
-
-    /**
-     * Specify if the mapped target resource's field is the id.
-     */
-    @NotNull
-    private Boolean connObjectKey = false;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    @NotNull
-    private Boolean password = false;
-
-    @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;
-
-    @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 connObjectKey;
-    }
-
-    @Override
-    public void setConnObjectKey(final boolean connObjectKey) {
-        this.connObjectKey = connObjectKey;
-    }
-
-    @Override
-    public boolean isPassword() {
-        return password;
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        this.password = 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;
-    }
-
-}
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
deleted file mode 100644
index d0d6ede63b..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ /dev/null
@@ -1,98 +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.jpa.entity.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import javax.persistence.Cacheable;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-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.Provision;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
-
-@Entity
-@Table(name = JPAMapping.TABLE)
-@Cacheable
-public class JPAMapping extends AbstractGeneratedKeyEntity implements Mapping {
-
-    private static final long serialVersionUID = 4316047254916259158L;
-
-    public static final String TABLE = "Mapping";
-
-    @OneToOne(optional = false)
-    private JPAProvision provision;
-
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
-    private List<JPAMappingItem> items = new ArrayList<>();
-
-    /**
-     * A JEXL expression for determining how to find the connector object link in external resource's space.
-     */
-    private String connObjectLink;
-
-    @Override
-    public Provision getProvision() {
-        return provision;
-    }
-
-    @Override
-    public void setProvision(final Provision provision) {
-        checkType(provision, JPAProvision.class);
-        this.provision = (JPAProvision) provision;
-    }
-
-    @Override
-    public boolean add(final MappingItem item) {
-        checkType(item, JPAMappingItem.class);
-        return items.contains((JPAMappingItem) item) || items.add((JPAMappingItem) item);
-    }
-
-    @Override
-    public List<? extends MappingItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public Optional<? extends MappingItem> getConnObjectKeyItem() {
-        return getItems().stream().filter(MappingItem::isConnObjectKey).findFirst();
-    }
-
-    @Override
-    public void setConnObjectKeyItem(final MappingItem item) {
-        item.setConnObjectKey(true);
-        this.add(item);
-    }
-
-    @Override
-    public String getConnObjectLink() {
-        return connObjectLink;
-    }
-
-    @Override
-    public void setConnObjectLink(final String connObjectLink) {
-        this.connObjectLink = connObjectLink;
-    }
-}
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
deleted file mode 100644
index a197e1128e..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.common.lib.types.IdRepoImplementationType;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-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.JPAImplementation;
-
-@Entity
-@Table(name = JPAMappingItem.TABLE)
-@Cacheable
-public class JPAMappingItem extends AbstractItem implements MappingItem {
-
-    private static final long serialVersionUID = 7383601853619332424L;
-
-    public static final String TABLE = "MappingItem";
-
-    @ManyToOne
-    private JPAMapping mapping;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name = TABLE + "Transformer",
-            joinColumns =
-            @JoinColumn(name = "item_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "implementation_id"),
-            uniqueConstraints =
-            @UniqueConstraint(columnNames = { "item_id", "implementation_id" }))
-    private List<JPAImplementation> transformers = new ArrayList<>();
-
-    @Override
-    public Mapping getMapping() {
-        return mapping;
-    }
-
-    @Override
-    public void setMapping(final Mapping mapping) {
-        checkType(mapping, JPAMapping.class);
-        this.mapping = (JPAMapping) mapping;
-    }
-
-    @Override
-    public boolean add(final Implementation transformer) {
-        checkType(transformer, JPAImplementation.class);
-        checkImplementationType(transformer, IdRepoImplementationType.ITEM_TRANSFORMER);
-        return transformers.contains((JPAImplementation) transformer)
-                || transformers.add((JPAImplementation) transformer);
-    }
-
-    @Override
-    public List<? extends Implementation> getTransformers() {
-        return transformers;
-    }
-}
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
deleted file mode 100644
index b7e11de95b..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnit.java
+++ /dev/null
@@ -1,146 +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.jpa.entity.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-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.syncope.core.persistence.api.entity.resource.ExternalResource;
-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.jpa.entity.AbstractGeneratedKeyEntity;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-@Entity
-@Table(name = JPAOrgUnit.TABLE)
-@Cacheable
-public class JPAOrgUnit extends AbstractGeneratedKeyEntity implements OrgUnit {
-
-    private static final long serialVersionUID = 8236319635989067603L;
-
-    public static final String TABLE = "OrgUnit";
-
-    @OneToOne
-    private JPAExternalResource resource;
-
-    @NotNull
-    private String objectClass;
-
-    @Lob
-    private String serializedSyncToken;
-
-    @NotNull
-    private Boolean ignoreCaseMatch = false;
-
-    @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;
-    }
-
-    @Override
-    public void setResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        this.resource = (JPAExternalResource) resource;
-    }
-
-    @Override
-    public ObjectClass getObjectClass() {
-        return Optional.ofNullable(objectClass).map(ObjectClass::new).orElse(null);
-    }
-
-    @Override
-    public void setObjectClass(final ObjectClass objectClass) {
-        this.objectClass = Optional.ofNullable(objectClass).map(ObjectClass::getObjectClassValue).orElse(null);
-    }
-
-    @Override
-    public SyncToken getSyncToken() {
-        return Optional.ofNullable(serializedSyncToken)
-            .map(syncToken -> POJOHelper.deserialize(syncToken, SyncToken.class)).orElse(null);
-    }
-
-    @Override
-    public String getSerializedSyncToken() {
-        return this.serializedSyncToken;
-    }
-
-    @Override
-    public void setSyncToken(final SyncToken syncToken) {
-        this.serializedSyncToken = Optional.ofNullable(syncToken).map(POJOHelper::serialize).orElse(null);
-    }
-
-    @Override
-    public boolean isIgnoreCaseMatch() {
-        return ignoreCaseMatch;
-    }
-
-    @Override
-    public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) {
-        this.ignoreCaseMatch = ignoreCaseMatch;
-    }
-
-    @Override
-    public String getConnObjectLink() {
-        return connObjectLink;
-    }
-
-    @Override
-    public void setConnObjectLink(final String connObjectLink) {
-        this.connObjectLink = connObjectLink;
-    }
-
-    @Override
-    public boolean add(final OrgUnitItem item) {
-        checkType(item, JPAOrgUnitItem.class);
-        return items.contains((JPAOrgUnitItem) item) || items.add((JPAOrgUnitItem) item);
-    }
-
-    @Override
-    public List<? extends OrgUnitItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public Optional<? extends OrgUnitItem> getConnObjectKeyItem() {
-        return getItems().stream().filter(OrgUnitItem::isConnObjectKey).findFirst();
-    }
-
-    @Override
-    public void setConnObjectKeyItem(final OrgUnitItem item) {
-        item.setConnObjectKey(true);
-        this.add(item);
-    }
-}
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
deleted file mode 100644
index 1882a13492..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAOrgUnitItem.java
+++ /dev/null
@@ -1,88 +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.jpa.entity.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import org.apache.syncope.common.lib.types.IdRepoImplementationType;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
-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.jpa.entity.JPAImplementation;
-
-@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;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name = TABLE + "Transformer",
-            joinColumns =
-            @JoinColumn(name = "item_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "implementation_id"),
-            uniqueConstraints =
-            @UniqueConstraint(columnNames = { "item_id", "implementation_id" }))
-    private List<JPAImplementation> transformers = 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 boolean isPassword() {
-        return false;
-    }
-
-    @Override
-    public boolean add(final Implementation transformer) {
-        checkType(transformer, JPAImplementation.class);
-        checkImplementationType(transformer, IdRepoImplementationType.ITEM_TRANSFORMER);
-        return transformers.contains((JPAImplementation) transformer)
-                || transformers.add((JPAImplementation) transformer);
-    }
-
-    @Override
-    public List<? extends Implementation> getTransformers() {
-        return transformers;
-    }
-}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
deleted file mode 100644
index 34b963b5fe..0000000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
+++ /dev/null
@@ -1,181 +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.jpa.entity.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.Lob;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import javax.validation.constraints.NotNull;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
-import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
-import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-@Entity
-@Table(name = JPAProvision.TABLE, uniqueConstraints =
-        @UniqueConstraint(columnNames = { "resource_id", "anyType_id" }))
-public class JPAProvision extends AbstractGeneratedKeyEntity implements Provision {
-
-    private static final long serialVersionUID = -1807889487945989443L;
-
-    public static final String TABLE = "Provision";
-
-    @ManyToOne
-    private JPAExternalResource resource;
-
-    @ManyToOne
-    private JPAAnyType anyType;
-
-    @NotNull
-    private String objectClass;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "provision_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "anyTypeClass_id"),
-            uniqueConstraints =
-            @UniqueConstraint(columnNames = { "provision_id", "anyTypeClass_id" }))
-    private List<JPAAnyTypeClass> auxClasses = new ArrayList<>();
-
-    @Lob
-    private String serializedSyncToken;
-
-    @Basic
-    private Boolean ignoreCaseMatch = false;
-
-    @ManyToOne
-    private JPAPlainSchema uidOnCreate;
-
-    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "provision")
-    private JPAMapping mapping;
-
-    @Override
-    public ExternalResource getResource() {
-        return resource;
-    }
-
-    @Override
-    public void setResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        this.resource = (JPAExternalResource) resource;
-    }
-
-    @Override
-    public AnyType getAnyType() {
-        return anyType;
-    }
-
-    @Override
-    public void setAnyType(final AnyType anyType) {
-        checkType(anyType, JPAAnyType.class);
-        this.anyType = (JPAAnyType) anyType;
-    }
-
-    @Override
-    public ObjectClass getObjectClass() {
-        return Optional.ofNullable(objectClass).map(ObjectClass::new).orElse(null);
-    }
-
-    @Override
-    public void setObjectClass(final ObjectClass objectClass) {
-        this.objectClass = Optional.ofNullable(objectClass).map(ObjectClass::getObjectClassValue).orElse(null);
-    }
-
-    @Override
-    public boolean add(final AnyTypeClass auxClass) {
-        checkType(auxClass, JPAAnyTypeClass.class);
-        return auxClasses.contains((JPAAnyTypeClass) auxClass) || auxClasses.add((JPAAnyTypeClass) auxClass);
-    }
-
-    @Override
-    public List<? extends AnyTypeClass> getAuxClasses() {
-        return auxClasses;
-    }
-
-    @Override
-    public SyncToken getSyncToken() {
-        return Optional.ofNullable(serializedSyncToken)
-                .map(syncToken -> POJOHelper.deserialize(syncToken, SyncToken.class)).orElse(null);
-    }
-
-    @Override
-    public String getSerializedSyncToken() {
-        return this.serializedSyncToken;
-    }
-
-    @Override
-    public void setSyncToken(final SyncToken syncToken) {
-        this.serializedSyncToken = Optional.ofNullable(syncToken).map(POJOHelper::serialize).orElse(null);
-    }
-
-    @Override
-    public boolean isIgnoreCaseMatch() {
-        return BooleanUtils.isNotFalse(ignoreCaseMatch);
-    }
-
-    @Override
-    public void setIgnoreCaseMatch(final boolean ignoreCaseMatch) {
-        this.ignoreCaseMatch = ignoreCaseMatch;
-    }
-
-    @Override
-    public PlainSchema getUidOnCreate() {
-        return uidOnCreate;
-    }
-
-    @Override
-    public void setUidOnCreate(final PlainSchema uidOnCreate) {
-        checkType(uidOnCreate, JPAPlainSchema.class);
-        this.uidOnCreate = (JPAPlainSchema) uidOnCreate;
-    }
-
-    @Override
-    public Mapping getMapping() {
-        return mapping;
-    }
-
-    @Override
-    public void setMapping(final Mapping mapping) {
-        checkType(mapping, JPAMapping.class);
-        this.mapping = (JPAMapping) mapping;
-    }
-}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 1d7a0ba20c..c2cd074de2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -25,9 +25,9 @@ import javax.persistence.MappedSuperclass;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ProvisioningTaskCheck;
 
 @MappedSuperclass
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java
index ab78b54b78..7a1e32d493 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplatePullTask.java
@@ -24,7 +24,7 @@ import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
-import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractAnyTemplate;
 
 @Entity
 @Table(name = JPAAnyTemplatePullTask.TABLE, uniqueConstraints =
@@ -48,5 +48,4 @@ public class JPAAnyTemplatePullTask extends AbstractAnyTemplate implements AnyTe
         checkType(pullTask, JPAPullTask.class);
         this.pullTask = (JPAPullTask) pullTask;
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
index b82ab70a67..518dfd26e6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -30,9 +30,9 @@ import javax.persistence.ManyToOne;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.PropagationTaskCheck;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.identityconnectors.framework.common.objects.Attribute;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
index 28b3bbb3d9..31cc9e21d0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPullTask.java
@@ -37,7 +37,6 @@ import javax.persistence.UniqueConstraint;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.IdMImplementationType;
 import org.apache.syncope.common.lib.types.PullMode;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
@@ -129,9 +128,9 @@ public class JPAPullTask extends AbstractProvisioningTask implements PullTask {
     }
 
     @Override
-    public Optional<? extends AnyTemplatePullTask> getTemplate(final AnyType anyType) {
+    public Optional<? extends AnyTemplatePullTask> getTemplate(final String anyType) {
         return templates.stream().
-                filter(template -> anyType != null && anyType.equals(template.getAnyType())).
+                filter(template -> anyType != null && anyType.equals(template.getAnyType().getKey())).
                 findFirst();
     }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
index cd5d8941e8..cccd14bc73 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java
@@ -40,14 +40,14 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPAPrivilege;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.Encryptor;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index 003ce8e063..edabbfa7d9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -48,10 +48,10 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
@@ -60,8 +60,8 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractGroupableRelatable;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPARole;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.Encryptor;
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 62fc7b6ef4..cee63643cf 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,24 +19,37 @@
 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.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.ItemContainer;
+import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.OrgUnit;
 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.Entity;
-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.ExternalResource;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 
 public class ExternalResourceValidator extends AbstractValidator<ExternalResourceCheck, ExternalResource> {
 
-    private static boolean isValid(final List<? extends Item> items, final ConstraintValidatorContext context) {
-        long connObjectKeys = items.stream().filter(Item::isConnObjectKey).count();
-        if (connObjectKeys != 1) {
+    private static boolean areItemsValid(
+            final ItemContainer itemContainer,
+            final ConstraintValidatorContext context) {
+
+        if (itemContainer.getItems().stream().
+                anyMatch(item -> item.getIntAttrName() == null
+                || item.getExtAttrName() == null
+                || item.getPurpose() == null)) {
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidMapping,
+                            "intAttrName, extAttrName and purpose must be specified for each item")).
+                    addPropertyNode("items").addConstraintViolation();
+            return false;
+        }
+
+        if (itemContainer.getConnObjectKeyItem().isEmpty()) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidMapping, "Single ConnObjectKey mapping is required")).
                     addPropertyNode("connObjectKey.size").addConstraintViolation();
@@ -51,7 +64,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             return true;
         }
 
-        return isValid(orgUnit.getItems(), context);
+        return areItemsValid(orgUnit, context);
     }
 
     private static boolean isValid(final Mapping mapping, final ConstraintValidatorContext context) {
@@ -61,7 +74,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
 
         boolean isValid = true;
 
-        long passwords = mapping.getItems().stream().filter(MappingItem::isPassword).count();
+        long passwords = mapping.getItems().stream().filter(Item::isPassword).count();
         if (passwords > 1) {
             context.buildConstraintViolationWithTemplate(
                     getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
@@ -69,7 +82,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             isValid = false;
         }
 
-        return isValid && isValid(mapping.getItems(), context);
+        return isValid && areItemsValid(mapping, context);
     }
 
     @Override
@@ -83,12 +96,12 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             return false;
         }
 
-        final Set<AnyType> anyTypes = new HashSet<>();
-        final Set<String> objectClasses = new HashSet<>();
+        Set<String> anyTypes = new HashSet<>();
+        Set<String> objectClasses = new HashSet<>();
         boolean validMappings = resource.getProvisions().stream().allMatch(provision -> {
             anyTypes.add(provision.getAnyType());
             if (provision.getObjectClass() != null) {
-                objectClasses.add(provision.getObjectClass().getObjectClassValue());
+                objectClasses.add(provision.getObjectClass());
             }
             return isValid(provision.getMapping(), context);
         });
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index e14d5560b4..1da1bc45b7 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -29,9 +29,11 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
+import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 
 @SpringJUnitConfig(classes = { PersistenceTestContext.class })
+@DirtiesContext
 public abstract class AbstractTest {
 
     @Autowired
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorManager.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorManager.java
index d7e29187a7..7e5442518a 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorManager.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorManager.java
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorManager;
 
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java
index 195dd67927..0bf3d16880 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java
@@ -32,10 +32,10 @@ import org.apache.syncope.common.lib.attr.JDBCAttrRepoConf;
 import org.apache.syncope.common.lib.attr.LDAPAttrRepoConf;
 import org.apache.syncope.common.lib.attr.StubAttrRepoConf;
 import org.apache.syncope.common.lib.attr.SyncopeAttrRepoConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AttrRepoState;
 import org.apache.syncope.core.persistence.api.dao.AttrRepoDAO;
 import org.apache.syncope.core.persistence.api.entity.am.AttrRepo;
-import org.apache.syncope.core.persistence.api.entity.am.AttrRepoItem;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -219,19 +219,19 @@ public class AttrRepoTest extends AbstractTest {
         attrRepo.setState(AttrRepoState.ACTIVE);
         attrRepo.setConf(conf);
 
-        AttrRepoItem keyMapping = entityFactory.newEntity(AttrRepoItem.class);
+        Item keyMapping = new Item();
         keyMapping.setIntAttrName("uid");
         keyMapping.setExtAttrName("username");
-        keyMapping.setAttrRepo(attrRepo);
-        attrRepo.add(keyMapping);
+        attrRepo.getItems().add(keyMapping);
 
-        AttrRepoItem fullnameMapping = entityFactory.newEntity(AttrRepoItem.class);
+        Item fullnameMapping = new Item();
         fullnameMapping.setIntAttrName("cn");
         fullnameMapping.setExtAttrName("fullname");
-        fullnameMapping.setAttrRepo(attrRepo);
-        attrRepo.add(fullnameMapping);
+        attrRepo.getItems().add(fullnameMapping);
 
         attrRepo = attrRepoDAO.save(attrRepo);
+        entityManager().flush();
+
         assertNotNull(attrRepo);
         assertNotNull(attrRepo.getKey());
         assertEquals(attrRepo, attrRepoDAO.find(attrRepo.getKey()));
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
index e00ab6c18b..fc8299fd19 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthModuleTest.java
@@ -39,10 +39,10 @@ import org.apache.syncope.common.lib.auth.SimpleMfaAuthModuleConf;
 import org.apache.syncope.common.lib.auth.StaticAuthModuleConf;
 import org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf;
 import org.apache.syncope.common.lib.auth.U2FAuthModuleConf;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AuthModuleState;
 import org.apache.syncope.core.persistence.api.dao.AuthModuleDAO;
 import org.apache.syncope.core.persistence.api.entity.am.AuthModule;
-import org.apache.syncope.core.persistence.api.entity.am.AuthModuleItem;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -245,7 +245,7 @@ public class AuthModuleTest extends AbstractTest {
         conf.setTimeToKillInSeconds(120);
         saveAuthModule("SimpleMfaAuthModuleConf", conf);
     }
-    
+
     @Test
     public void saveWithU2FModule() {
         U2FAuthModuleConf conf = new U2FAuthModuleConf();
@@ -438,19 +438,19 @@ public class AuthModuleTest extends AbstractTest {
         module.setState(AuthModuleState.ACTIVE);
         module.setConf(conf);
 
-        AuthModuleItem keyMapping = entityFactory.newEntity(AuthModuleItem.class);
+        Item keyMapping = new Item();
         keyMapping.setIntAttrName("uid");
         keyMapping.setExtAttrName("username");
-        keyMapping.setAuthModule(module);
-        module.add(keyMapping);
+        module.getItems().add(keyMapping);
 
-        AuthModuleItem fullnameMapping = entityFactory.newEntity(AuthModuleItem.class);
+        Item fullnameMapping = new Item();
         fullnameMapping.setIntAttrName("cn");
         fullnameMapping.setExtAttrName("fullname");
-        fullnameMapping.setAuthModule(module);
-        module.add(fullnameMapping);
+        module.getItems().add(fullnameMapping);
 
         module = authModuleDAO.save(module);
+        entityManager().flush();
+
         assertNotNull(module);
         assertNotNull(module.getKey());
         assertEquals(module, authModuleDAO.find(module.getKey()));
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index 1607f0d7ee..6fa39397fb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -90,7 +90,7 @@ public class PolicyTest extends AbstractTest {
         PullPolicy pullPolicy = policyDAO.find("880f8553-069b-4aed-9930-2cd53873f544");
         assertNotNull(pullPolicy);
 
-        PullCorrelationRuleEntity pullCR = pullPolicy.getCorrelationRule(anyTypeDAO.findUser()).orElse(null);
+        PullCorrelationRuleEntity pullCR = pullPolicy.getCorrelationRule(anyTypeDAO.findUser().getKey()).orElse(null);
         assertNotNull(pullCR);
         DefaultPullCorrelationRuleConf pullCRConf =
                 POJOHelper.deserialize(pullCR.getImplementation().getBody(), DefaultPullCorrelationRuleConf.class);
@@ -102,7 +102,7 @@ public class PolicyTest extends AbstractTest {
         PushPolicy pushPolicy = policyDAO.find("fb6530e5-892d-4f47-a46b-180c5b6c5c83");
         assertNotNull(pushPolicy);
 
-        PushCorrelationRuleEntity pushCR = pushPolicy.getCorrelationRule(anyTypeDAO.findUser()).orElse(null);
+        PushCorrelationRuleEntity pushCR = pushPolicy.getCorrelationRule(anyTypeDAO.findUser().getKey()).orElse(null);
         assertNotNull(pushCR);
         DefaultPushCorrelationRuleConf pushCRConf =
                 POJOHelper.deserialize(pushCR.getImplementation().getBody(), DefaultPushCorrelationRuleConf.class);
@@ -214,9 +214,9 @@ public class PolicyTest extends AbstractTest {
 
         assertNotNull(pullPolicy);
         assertEquals(pullURuleName,
-                pullPolicy.getCorrelationRule(anyTypeDAO.findUser()).get().getImplementation().getKey());
+                pullPolicy.getCorrelationRule(anyTypeDAO.findUser().getKey()).get().getImplementation().getKey());
         assertEquals(pullGRuleName,
-                pullPolicy.getCorrelationRule(anyTypeDAO.findGroup()).get().getImplementation().getKey());
+                pullPolicy.getCorrelationRule(anyTypeDAO.findGroup().getKey()).get().getImplementation().getKey());
     }
 
     @Test
@@ -258,9 +258,9 @@ public class PolicyTest extends AbstractTest {
 
         assertNotNull(pushPolicy);
         assertEquals(pushURuleName,
-                pushPolicy.getCorrelationRule(anyTypeDAO.findUser()).get().getImplementation().getKey());
+                pushPolicy.getCorrelationRule(anyTypeDAO.findUser().getKey()).get().getImplementation().getKey());
         assertEquals(pushGRuleName,
-                pushPolicy.getCorrelationRule(anyTypeDAO.findGroup()).get().getImplementation().getKey());
+                pushPolicy.getCorrelationRule(anyTypeDAO.findGroup().getKey()).get().getImplementation().getKey());
     }
 
     @Test
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
index 297d2e975a..8a9677e4ed 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -29,6 +29,9 @@ import static org.junit.jupiter.api.Assertions.fail;
 import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -36,10 +39,7 @@ import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntit
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-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.Provision;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
 import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
@@ -71,11 +71,11 @@ public class ResourceTest extends AbstractTest {
         assertEquals("net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
         assertEquals("net.tirasa.connid.bundles.soap", connector.getBundleName());
 
-        Mapping mapping = resource.getProvision(anyTypeDAO.findUser()).get().getMapping();
+        Mapping mapping = resource.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping();
         assertFalse(mapping.getItems().isEmpty());
 
         assertTrue(mapping.getItems().stream().
-                anyMatch(item -> "7f55b09c-b573-41dc-a9eb-ccd80bd3ea7a".equals(item.getKey())));
+                anyMatch(item -> "email".equals(item.getExtAttrName()) && "email".equals(item.getIntAttrName())));
 
         try {
             resourceDAO.authFind("ws-target-resource-1");
@@ -117,7 +117,7 @@ public class ResourceTest extends AbstractTest {
     public void getConnObjectKey() {
         ExternalResource resource = resourceDAO.find("ws-target-resource-2");
         assertNotNull(resource);
-        assertEquals("fullname", resource.getProvision(anyTypeDAO.findUser()).get().
+        assertEquals("fullname", resource.getProvision(anyTypeDAO.findUser().getKey()).get().
                 getMapping().getConnObjectKeyItem().get().getIntAttrName());
     }
 
@@ -127,17 +127,15 @@ public class ResourceTest extends AbstractTest {
         resource.setKey("ws-target-resource-basic-save");
         resource.setPropagationPriority(2);
 
-        Provision provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findUser());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
+        Provision provision = new Provision();
+        provision.setAnyType(anyTypeDAO.findUser().getKey());
+        provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provision);
 
-        Mapping mapping = entityFactory.newEntity(Mapping.class);
-        mapping.setProvision(provision);
+        Mapping mapping = new Mapping();
         provision.setMapping(mapping);
 
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        Item connObjectKey = new Item();
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("fullname");
         connObjectKey.setPurpose(MappingPurpose.BOTH);
@@ -148,11 +146,11 @@ public class ResourceTest extends AbstractTest {
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
-
+        entityManager().flush();
         assertNotNull(actual);
         assertNotNull(actual.getConnector());
-        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).get().getMapping());
-        assertFalse(actual.getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().isEmpty());
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping());
+        assertFalse(actual.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().isEmpty());
         assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
     }
 
@@ -165,17 +163,15 @@ public class ResourceTest extends AbstractTest {
             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
             resource.setConnector(connector);
 
-            Provision provision = entityFactory.newEntity(Provision.class);
-            provision.setAnyType(anyTypeDAO.findUser());
-            provision.setObjectClass(ObjectClass.ACCOUNT);
-            provision.setResource(resource);
-            resource.add(provision);
+            Provision provision = new Provision();
+            provision.setAnyType(anyTypeDAO.findUser().getKey());
+            provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resource.getProvisions().add(provision);
 
-            Mapping mapping = entityFactory.newEntity(Mapping.class);
-            mapping.setProvision(provision);
+            Mapping mapping = new Mapping();
             provision.setMapping(mapping);
 
-            MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+            Item connObjectKey = new Item();
             connObjectKey.setConnObjectKey(true);
             mapping.add(connObjectKey);
 
@@ -193,22 +189,20 @@ public class ResourceTest extends AbstractTest {
             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
             resource.setConnector(connector);
 
-            Provision provision = entityFactory.newEntity(Provision.class);
-            provision.setAnyType(anyTypeDAO.findUser());
-            provision.setObjectClass(ObjectClass.ACCOUNT);
-            provision.setResource(resource);
-            resource.add(provision);
+            Provision provision = new Provision();
+            provision.setAnyType(anyTypeDAO.findUser().getKey());
+            provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resource.getProvisions().add(provision);
 
-            Mapping mapping = entityFactory.newEntity(Mapping.class);
-            mapping.setProvision(provision);
+            Mapping mapping = new Mapping();
             provision.setMapping(mapping);
 
-            MappingItem item = entityFactory.newEntity(MappingItem.class);
+            Item item = new Item();
             item.setConnObjectKey(true);
             item.setIntAttrName("fullname");
             mapping.add(item);
 
-            item = entityFactory.newEntity(MappingItem.class);
+            item = new Item();
             item.setIntAttrName("userId");
             mapping.add(item);
 
@@ -222,27 +216,24 @@ public class ResourceTest extends AbstractTest {
             ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
             resource.setKey("invalidProvision");
 
-            Provision provision = entityFactory.newEntity(Provision.class);
-            provision.setAnyType(anyTypeDAO.findUser());
-            provision.setObjectClass(ObjectClass.ACCOUNT);
-            provision.setResource(resource);
-            resource.add(provision);
+            Provision provision = new Provision();
+            provision.setAnyType(anyTypeDAO.findUser().getKey());
+            provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resource.getProvisions().add(provision);
 
-            Mapping mapping = entityFactory.newEntity(Mapping.class);
-            mapping.setProvision(provision);
+            Mapping mapping = new Mapping();
             provision.setMapping(mapping);
 
-            MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+            Item connObjectKey = new Item();
             connObjectKey.setExtAttrName("username");
             connObjectKey.setIntAttrName("fullname");
             connObjectKey.setPurpose(MappingPurpose.BOTH);
             mapping.setConnObjectKeyItem(connObjectKey);
 
-            provision = entityFactory.newEntity(Provision.class);
-            provision.setAnyType(anyTypeDAO.findGroup());
-            provision.setObjectClass(ObjectClass.ACCOUNT);
-            provision.setResource(resource);
-            resource.add(provision);
+            provision = new Provision();
+            provision.setAnyType(anyTypeDAO.findGroup().getKey());
+            provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resource.getProvisions().add(provision);
 
             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
             resource.setConnector(connector);
@@ -258,27 +249,24 @@ public class ResourceTest extends AbstractTest {
         resource.setKey("ws-target-resource-virtual-mapping");
         resource.setPropagationPriority(2);
 
-        Provision provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findUser());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
+        Provision provision = new Provision();
+        provision.setAnyType(anyTypeDAO.findUser().getKey());
+        provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provision);
 
-        Mapping mapping = entityFactory.newEntity(Mapping.class);
-        mapping.setProvision(provision);
+        Mapping mapping = new Mapping();
         provision.setMapping(mapping);
 
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        Item connObjectKey = new Item();
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("fullname");
         connObjectKey.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(connObjectKey);
 
-        MappingItem virtualMapItem = entityFactory.newEntity(MappingItem.class);
+        Item virtualMapItem = new Item();
         virtualMapItem.setIntAttrName("virtualReadOnly");
         virtualMapItem.setExtAttrName("TEST");
         virtualMapItem.setPurpose(MappingPurpose.PROPAGATION);
-        virtualMapItem.setMapping(mapping);
         mapping.add(virtualMapItem);
 
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
@@ -295,29 +283,27 @@ public class ResourceTest extends AbstractTest {
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        Provision provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findUser());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
+        Provision provision = new Provision();
+        provision.setAnyType(anyTypeDAO.findUser().getKey());
+        provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provision);
 
-        Mapping mapping = entityFactory.newEntity(Mapping.class);
-        mapping.setProvision(provision);
+        Mapping mapping = new Mapping();
         provision.setMapping(mapping);
 
-        MappingItem item = entityFactory.newEntity(MappingItem.class);
+        Item item = new Item();
         item.setIntAttrName("fullname");
         item.setExtAttrName("fullname");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        item = entityFactory.newEntity(MappingItem.class);
+        item = new Item();
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
-        item = entityFactory.newEntity(MappingItem.class);
+        item = new Item();
         item.setIntAttrName("mderiveddata");
         item.setExtAttrName("mderiveddata");
         item.setPurpose(MappingPurpose.PROPAGATION);
@@ -325,9 +311,10 @@ public class ResourceTest extends AbstractTest {
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
+        entityManager().flush();
         assertNotNull(actual);
 
-        assertEquals(3, actual.getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size());
+        assertEquals(3, actual.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().size());
     }
 
     @Test
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
index 04d247004d..238a3fd370 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -33,7 +33,7 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.user.User;
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
index b723f24d8b..97ed8059f9 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
@@ -27,13 +27,11 @@ import static org.junit.jupiter.api.Assertions.fail;
 import java.util.List;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 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.Provision;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -47,6 +45,9 @@ public class VirSchemaTest extends AbstractTest {
     @Autowired
     private ExternalResourceDAO resourceDAO;
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Test
     public void findAll() {
         List<VirSchema> list = virSchemaDAO.findAll();
@@ -67,13 +68,10 @@ public class VirSchemaTest extends AbstractTest {
 
     @Test
     public void save() {
-        ExternalResource csv = resourceDAO.find("resource-csv");
-        Provision provision = csv.getProvision(ObjectClass.ACCOUNT).get();
-        assertNotNull(provision);
-
         VirSchema virSchema = entityFactory.newEntity(VirSchema.class);
         virSchema.setKey("virtual");
-        virSchema.setProvision(provision);
+        virSchema.setResource(resourceDAO.find("resource-csv"));
+        virSchema.setAnyType(anyTypeDAO.findUser());
         virSchema.setReadonly(true);
         virSchema.setExtAttrName("EXT_ATTR");
 
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
index 8573ed9f6c..6aa317109b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index 807b6cbed3..c9c1c7d159 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -155,12 +155,16 @@ public class GroupTest extends AbstractTest {
 
     @Test
     public void delete() {
+        Collection<Group> groups = userDAO.findAllGroups(userDAO.findByUsername("verdi"));
+        assertTrue(groups.stream().anyMatch(g -> "b1f7c12d-ec83-441f-a50e-1691daaedf3b".equals(g.getKey())));
+        int before = userDAO.findAllGroups(userDAO.findByUsername("verdi")).size();
+
         groupDAO.delete("b1f7c12d-ec83-441f-a50e-1691daaedf3b");
 
         entityManager().flush();
 
         assertNull(groupDAO.find("b1f7c12d-ec83-441f-a50e-1691daaedf3b"));
-        assertEquals(userDAO.findAllGroups(userDAO.findByUsername("verdi")).size(), 2);
+        assertEquals(before - 1, userDAO.findAllGroups(userDAO.findByUsername("verdi")).size());
         assertNull(findPlainAttr("f82fc61f-8e74-4a4b-9f9e-b8a41f38aad9", GPlainAttr.class));
         assertNull(findPlainAttrValue("49f35879-2510-4f11-a901-24152f753538", GPlainAttrValue.class));
         assertNotNull(plainSchemaDAO.find("icon"));
@@ -234,8 +238,7 @@ public class GroupTest extends AbstractTest {
         // 3. verify that expected users have the created group dynamically assigned
         List<String> members = groupDAO.findUDynMembers(actual);
         assertEquals(2, members.size());
-        assertEquals(Set.of("c9b2dec2-00a7-4855-97c0-d854842b4b24", newUserKey),
-                new HashSet<>(members));
+        assertEquals(Set.of("c9b2dec2-00a7-4855-97c0-d854842b4b24", newUserKey), new HashSet<>(members));
 
         user = userDAO.findByUsername("bellini");
         assertNotNull(user);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
index 6c65f91be6..c107d59093 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
@@ -28,10 +28,12 @@ import static org.junit.jupiter.api.Assertions.fail;
 import java.util.List;
 import java.util.UUID;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.persistence.EntityExistsException;
-import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
@@ -40,11 +42,9 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.SchemaLabel;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.persistence.jpa.entity.JPASchemaLabel;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
 import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
 import org.junit.jupiter.api.AfterAll;
@@ -76,7 +76,8 @@ public class PlainSchemaTest extends AbstractTest {
 
     @BeforeAll
     public static void setAuthContext() {
-        List<GrantedAuthority> authorities = IdRepoEntitlement.values().stream().
+        List<GrantedAuthority> authorities = Stream.concat(
+                IdRepoEntitlement.values().stream(), IdMEntitlement.values().stream()).
                 map(entitlement -> new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM)).
                 collect(Collectors.toList());
 
@@ -109,12 +110,12 @@ public class PlainSchemaTest extends AbstractTest {
         }
     }
 
-    private List<MappingItem> getMappingItems(final String intAttrName) {
-        TypedQuery<MappingItem> mapItemsQuery = entityManager().createQuery(
-                "SELECT e FROM " + JPAMappingItem.class.getSimpleName() + " e WHERE e.intAttrName=:intAttrName",
-                MappingItem.class);
-        mapItemsQuery.setParameter("intAttrName", intAttrName);
-        return mapItemsQuery.getResultList();
+    private List<Item> getMappingItems(final String intAttrName) {
+        return resourceDAO.findAll().stream().
+                flatMap(resource -> resource.getProvisions().stream()).
+                flatMap(provision -> provision.getMapping().getItems().stream()).
+                filter(item -> intAttrName.equals(item.getIntAttrName())).
+                collect(Collectors.toList());
     }
 
     @Test
@@ -122,7 +123,7 @@ public class PlainSchemaTest extends AbstractTest {
         // fullname is mapped as ConnObjectKey for ws-target-resource-2, need to swap it otherwise validation errors 
         // will be raised
         resourceDAO.find("ws-target-resource-2").
-                getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().
+                getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().
                 forEach(item -> {
                     if ("fullname".equals(item.getIntAttrName())) {
                         item.setConnObjectKey(false);
@@ -136,7 +137,7 @@ public class PlainSchemaTest extends AbstractTest {
         assertNotNull(schema);
 
         // check for associated mappings
-        List<MappingItem> mapItems = getMappingItems("fullname");
+        List<Item> mapItems = getMappingItems("fullname");
         assertFalse(mapItems.isEmpty());
 
         // delete user schema fullname
@@ -148,8 +149,6 @@ public class PlainSchemaTest extends AbstractTest {
         schema = plainSchemaDAO.find("fullname");
         assertNull(schema);
 
-        plainSchemaDAO.clear();
-
         // check for mappings deletion
         mapItems = getMappingItems("fullname");
         assertTrue(mapItems.isEmpty());
@@ -167,7 +166,7 @@ public class PlainSchemaTest extends AbstractTest {
         assertNotNull(schema);
 
         // check for associated mappings
-        List<MappingItem> mapItems = getMappingItems("surname");
+        List<Item> mapItems = getMappingItems("surname");
         assertFalse(mapItems.isEmpty());
 
         // check for labels
@@ -193,12 +192,12 @@ public class PlainSchemaTest extends AbstractTest {
     @Test
     public void deleteFirstname() {
         int pre = resourceDAO.find("resource-db-pull").
-                getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size();
+                getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().size();
 
         plainSchemaDAO.delete("firstname");
         assertNull(plainSchemaDAO.find("firstname"));
 
         assertEquals(pre - 1, resourceDAO.find("resource-db-pull").
-                getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size());
+                getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().size());
     }
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
index 6dbd8d2acd..728a70f1a9 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -27,6 +27,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.to.Item;
+import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -35,18 +38,12 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-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.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnit;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -73,9 +70,6 @@ public class ResourceTest extends AbstractTest {
     @Autowired
     private PolicyDAO policyDAO;
 
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
     @Test
     public void createWithPasswordPolicy() {
         final String resourceName = "resourceWithPasswordPolicy";
@@ -113,46 +107,42 @@ public class ResourceTest extends AbstractTest {
 
         resource.setConnector(connector);
 
-        Provision provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findUser());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
+        Provision provision = new Provision();
+        provision.setAnyType(anyTypeDAO.findUser().getKey());
+        provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resource.getProvisions().add(provision);
 
-        Mapping mapping = entityFactory.newEntity(Mapping.class);
-        mapping.setProvision(provision);
+        Mapping mapping = new Mapping();
         provision.setMapping(mapping);
 
         // specify mappings
         for (int i = 0; i < 3; i++) {
-            MappingItem item = entityFactory.newEntity(MappingItem.class);
+            Item item = new Item();
             item.setExtAttrName("test" + i);
             item.setIntAttrName("nonexistent" + i);
             item.setMandatoryCondition("false");
             item.setPurpose(MappingPurpose.PULL);
             mapping.add(item);
-            item.setMapping(mapping);
         }
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        Item connObjectKey = new Item();
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("username");
         connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(connObjectKey);
-        connObjectKey.setMapping(mapping);
 
         // map a derived attribute
-        MappingItem derived = entityFactory.newEntity(MappingItem.class);
+        Item derived = new Item();
         derived.setConnObjectKey(false);
         derived.setExtAttrName("fullname");
         derived.setIntAttrName("cn");
         derived.setPurpose(MappingPurpose.PROPAGATION);
         mapping.add(derived);
-        derived.setMapping(mapping);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
+        entityManager().flush();
         assertNotNull(actual);
-        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).get().getMapping());
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping());
 
         entityManager().flush();
         resourceDAO.detach(actual);
@@ -180,7 +170,8 @@ public class ResourceTest extends AbstractTest {
         assertTrue(resource.getConnector().equals(connector));
 
         // check mappings
-        List<? extends MappingItem> items = resource.getProvision(anyTypeDAO.findUser()).get().getMapping().getItems();
+        List<Item> items = resource.getProvision(
+                anyTypeDAO.findUser().getKey()).get().getMapping().getItems();
         assertNotNull(items);
         assertEquals(5, items.size());
 
@@ -244,71 +235,26 @@ public class ResourceTest extends AbstractTest {
         propagationTasks.forEach(task -> assertNull(taskDAO.find(task.getKey())));
     }
 
-    @Test
-    public void emptyMapping() {
-        ExternalResource ldap = resourceDAO.find("resource-ldap");
-        assertNotNull(ldap);
-        assertNotNull(ldap.getProvision(anyTypeDAO.findUser()).get().getMapping());
-        assertNotNull(ldap.getProvision(anyTypeDAO.findGroup()).get().getMapping());
-
-        // need to avoid any class not defined in this Maven module
-        ldap.getPropagationActions().clear();
-
-        List<? extends MappingItem> items = ldap.getProvision(anyTypeDAO.findGroup()).get().getMapping().getItems();
-        assertNotNull(items);
-        assertFalse(items.isEmpty());
-        List<String> itemKeys = items.stream().map(MappingItem::getKey).collect(Collectors.toList());
-
-        Provision groupProvision = ldap.getProvision(anyTypeDAO.findGroup()).get();
-        virSchemaDAO.findByProvision(groupProvision).
-                forEach(schema -> virSchemaDAO.delete(schema.getKey()));
-        ldap.getProvisions().remove(groupProvision);
-
-        resourceDAO.save(ldap);
-        entityManager().flush();
-
-        itemKeys.forEach(itemKey -> assertNull(entityManager().find(JPAMappingItem.class, itemKey)));
-    }
-
-    @Test
-    public void updateRemoveOrgUnit() {
-        ExternalResource resource = resourceDAO.find("resource-ldap-orgunit");
-        assertNotNull(resource);
-        assertNotNull(resource.getOrgUnit());
-
-        String orgUnitKey = resource.getOrgUnit().getKey();
-        assertNotNull(entityManager().find(JPAOrgUnit.class, orgUnitKey));
-
-        resource.getOrgUnit().setResource(null);
-        resource.setOrgUnit(null);
-
-        resourceDAO.save(resource);
-        entityManager().flush();
-
-        resource = resourceDAO.find("resource-ldap-orgunit");
-        assertNull(resource.getOrgUnit());
-
-        assertNull(entityManager().find(JPAOrgUnit.class, orgUnitKey));
-    }
-
     @Test
     public void issue243() {
         ExternalResource csv = resourceDAO.find("resource-csv");
         assertNotNull(csv);
 
-        int origMapItems = csv.getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size();
+        int origMapItems = csv.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().size();
 
-        MappingItem newMapItem = entityFactory.newEntity(MappingItem.class);
+        Item newMapItem = new Item();
         newMapItem.setIntAttrName("TEST");
         newMapItem.setExtAttrName("TEST");
         newMapItem.setPurpose(MappingPurpose.PROPAGATION);
-        csv.getProvision(anyTypeDAO.findUser()).get().getMapping().add(newMapItem);
+        csv.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().add(newMapItem);
 
         resourceDAO.save(csv);
         entityManager().flush();
 
         csv = resourceDAO.find("resource-csv");
         assertNotNull(csv);
-        assertEquals(origMapItems + 1, csv.getProvision(anyTypeDAO.findUser()).get().getMapping().getItems().size());
+        assertEquals(
+                origMapItems + 1,
+                csv.getProvision(anyTypeDAO.findUser().getKey()).get().getMapping().getItems().size());
     }
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index 049ac3f87a..402860d27b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -26,7 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -143,9 +142,7 @@ public class RoleTest extends AbstractTest {
         // 3. verify that expected users have the created role dynamically assigned
         List<String> members = roleDAO.findDynMembers(actual);
         assertEquals(2, members.size());
-        assertEquals(
-                Set.of("c9b2dec2-00a7-4855-97c0-d854842b4b24", newUserKey),
-                new HashSet<>(members));
+        assertEquals(Set.of("c9b2dec2-00a7-4855-97c0-d854842b4b24", newUserKey), new HashSet<>(members));
 
         user = userDAO.find("c9b2dec2-00a7-4855-97c0-d854842b4b24");
         assertNotNull(user);
@@ -227,7 +224,7 @@ public class RoleTest extends AbstractTest {
 
         delegation = delegationDAO.find(delegation.getKey());
 
-        assertEquals(Collections.singletonList(delegation), delegationDAO.findByRole(reviewer));
+        assertEquals(List.of(delegation), delegationDAO.findByRole(reviewer));
 
         roleDAO.delete(reviewer.getKey());
 
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index c60e245289..c3d7218f38 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -47,8 +47,8 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
index 353e4d55d5..8f5c75a8f5 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
@@ -119,9 +119,7 @@ public class UserTest extends AbstractTest {
         User user = userDAO.findByUsername("bellini");
         assertNotNull(user);
         assertEquals(1, user.getMemberships().size());
-        assertEquals(
-                "bf825fe1-7320-4a54-bd64-143b5c18ab97",
-                user.getMemberships().get(0).getRightEnd().getKey());
+        assertEquals("bf825fe1-7320-4a54-bd64-143b5c18ab97", user.getMemberships().get(0).getRightEnd().getKey());
 
         user.remove(user.getMemberships().get(0));
 
@@ -158,9 +156,7 @@ public class UserTest extends AbstractTest {
 
         user = userDAO.findByUsername("bellini");
         assertEquals(1, user.getRelationships().size());
-        assertEquals(
-                "8559d14d-58c2-46eb-a2d4-a7d35161e8f8",
-                user.getRelationships().get(0).getRightEnd().getKey());
+        assertEquals("8559d14d-58c2-46eb-a2d4-a7d35161e8f8", user.getRelationships().get(0).getRightEnd().getKey());
     }
 
     @Test
@@ -244,6 +240,7 @@ public class UserTest extends AbstractTest {
         User user = userDAO.findByUsername("vivaldi");
         user.getLinkedAccounts().stream().filter(Objects::nonNull).forEach(account -> account.setOwner(null));
         user.getLinkedAccounts().clear();
+        entityManager().flush();
 
         LinkedAccount account = entityFactory.newEntity(LinkedAccount.class);
         account.setOwner(user);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java
index b9e6f40b03..7fab7be0c3 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java
@@ -23,12 +23,12 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import org.apache.syncope.common.lib.to.Item;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,15 +48,17 @@ public class VirSchemaTest extends AbstractTest {
 
     @Test
     public void deal() {
-        Provision provision = resourceDAO.find("ws-target-resource-1").getProvision(anyTypeDAO.findUser()).get();
-        assertNotNull(provision);
-        assertTrue(virSchemaDAO.findByProvision(provision).isEmpty());
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+        assertTrue(virSchemaDAO.find(resource).isEmpty());
+        assertTrue(virSchemaDAO.find(resource.getKey(), anyTypeDAO.findUser().getKey()).isEmpty());
 
         VirSchema virSchema = entityFactory.newEntity(VirSchema.class);
         virSchema.setKey("vSchema");
         virSchema.setReadonly(true);
         virSchema.setExtAttrName("EXT_ATTR");
-        virSchema.setProvision(provision);
+        virSchema.setResource(resource);
+        virSchema.setAnyType(anyTypeDAO.findUser());
 
         virSchemaDAO.save(virSchema);
         entityManager().flush();
@@ -66,12 +68,13 @@ public class VirSchemaTest extends AbstractTest {
         assertTrue(virSchema.isReadonly());
         assertEquals("EXT_ATTR", virSchema.getExtAttrName());
 
-        provision = resourceDAO.find("ws-target-resource-1").getProvision(anyTypeDAO.findUser()).get();
-        assertNotNull(provision);
-        assertFalse(virSchemaDAO.findByProvision(provision).isEmpty());
-        assertTrue(virSchemaDAO.findByProvision(provision).contains(virSchema));
+        assertFalse(virSchemaDAO.find(resource).isEmpty());
+        assertTrue(virSchemaDAO.find(resource).contains(virSchema.getKey()));
 
-        MappingItem item = virSchema.asLinkingMappingItem();
+        assertFalse(virSchemaDAO.find(resource.getKey(), anyTypeDAO.findUser().getKey()).isEmpty());
+        assertTrue(virSchemaDAO.find(resource.getKey(), anyTypeDAO.findUser().getKey()).contains(virSchema));
+
+        Item item = virSchema.asLinkingMappingItem();
         assertNotNull(item);
         assertEquals(virSchema.getKey(), item.getIntAttrName());
     }
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 1336795aec..5d4325c9bb 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -53,18 +53,18 @@ under the License.
               jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf","authModules":["LdapAuthenticationTest"]}'/>
 
   <!-- Access policies -->
-  <AccessPolicy id="419935c7-deb3-40b3-8a9a-683037e523a2" name="MyDefaultAccessPolicyConf"
-                jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf","name":"MyDefaultAccessPolicyConf","enabled":true,"ssoEnabled":true}'/>
+  <AccessPolicy aporder="0" ssoEnabled="1" name="MyDefaultAccessPolicyConf" caseInsensitive="1" id="419935c7-deb3-40b3-8a9a-683037e523a2" enabled="1" requireAllAttributes="1"/>
 
   <!-- Attr Release Policies -->
-  <AttrReleasePolicy id="319935c7-deb3-40b3-8a9a-683037e523a2" name="AllowedAttrReleasePolicy"
-                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"AllowedAttrReleasePolicy","allowedAttributes":["cn","givenName","uid"]}'/>
-  <AttrReleasePolicy id="219935c7-deb3-40b3-8a9a-683037e523a2" name="DenyAttrReleasePolicy"
-                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.AllowedAttrReleasePolicyConf","name":"DenyAttrReleasePolicyConf"}'/>
+  <AttrReleasePolicy arporder="0" name="DenyAttrReleasePolicy" id="219935c7-deb3-40b3-8a9a-683037e523a2"
+                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf","allowedAttrs":[],"excludedAttrs":[],"includeOnlyAttrs":[],"principalIdAttr":null,"principalAttrRepoConf":{"mergingStrategy":"MULTIVALUED","ignoreResolvedAttributes":false,"expiration":0,"timeUnit":"HOURS","attrRepos":[]}}'/>
+  <AttrReleasePolicy arporder="0" name="AllowedAttrReleasePolicy" id="319935c7-deb3-40b3-8a9a-683037e523a2"
+                     jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf","allowedAttrs":["cn","givenName","uid"],"excludedAttrs":[],"includeOnlyAttrs":[],"principalIdAttr":null,"principalAttrRepoConf":{"mergingStrategy":"MULTIVALUED","ignoreResolvedAttributes":false,"expiration":0,"timeUnit":"HOURS","attrRepos":[]}}'/>
 
   <!-- Authentication modules -->
   <AuthModule id="DefaultLDAPAuthModule" authModuleState="ACTIVE"
-              description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}'/>
+              description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}'
+              items='[{"intAttrName":"mail","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"givenName","extAttrName":"givenName","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"sn","extAttrName":"sn","conn [...]
   <AuthModule id="DefaultJDBCAuthModule" authModuleState="ACTIVE"
               description="JDBC auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","sql":"SELECT * FROM users_table WHERE name=?", "fieldPassword": "password"}'/>
   <AuthModule id="DefaultGoogleMfaAuthModule" authModuleState="ACTIVE"
@@ -82,43 +82,22 @@ under the License.
   <AuthModule id="DefaultStaticAuthModule" authModuleState="ACTIVE"
               description="Static auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.StaticAuthModuleConf","users":{"syncope1": "$cynop3"}}'/>
   <AuthModule id="DefaultSyncopeAuthModule" authModuleState="ACTIVE"
-              description="Syncope auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","domain":"Master"}'/>
+              description="Syncope auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf","domain":"Master"}'
+              items='[{"intAttrName":"syncopeUserAttr_surname","extAttrName":"family_name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"syncopeUserAttr_fullname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAtt [...]
   <AuthModule id="DefaultU2FAuthModule" authModuleState="ACTIVE"
               description="U2F auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.U2FAuthModuleConf","expireDevices":40}'/>
 
-  <AuthModuleItem id="26678936-af09-48b8-a789-36af0918b87d" extAttrName="family_name" intAttrName="syncopeUserAttr_surname"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="a66ed3b1-07be-4a6e-aed3-b107be8a6e75" extAttrName="name" intAttrName="syncopeUserAttr_fullname"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="edc26674-fac5-4a60-8266-74fac5ca6020" extAttrName="given_name" intAttrName="syncopeUserAttr_firstname" 
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="520eeba7-e00a-4221-8eeb-a7e00aa22159" extAttrName="email" intAttrName="syncopeUserAttr_email"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-  <AuthModuleItem id="8360509b-7d8e-4796-aa79-3c5ccc8671e6" extAttrName="groups" intAttrName="syncopeUserMemberships"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultSyncopeAuthModule"/>
-
-  <AuthModuleItem id="8437a40d-d74e-400c-9628-72eba9e30a13" extAttrName="mail" intAttrName="mail"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="1b7a8347-810b-44f2-85ae-58f9e4bedc37" extAttrName="givenName" intAttrName="givenName"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="b06cd5fe-c86b-48d4-8acc-4a46c12bea41" extAttrName="sn" intAttrName="sn" 
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-  <AuthModuleItem id="a1933059-e64f-409f-a86c-5b54da21787e" extAttrName="cn" intAttrName="cn"
-                  password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" authModule_id="DefaultLDAPAuthModule"/>
-
   <!-- Attribute repositories -->
   <AttrRepo id="DefaultLDAPAttrRepo" attrRepoState="ACTIVE"
             description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:1389","bindDn":"uid=admin,ou=system","bindCredential":"secret","baseDn":"ou=People,o=isp","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/>
   <AttrRepo id="DefaultJDBCAttrRepo" attrRepoState="ACTIVE"
             description="JDBC attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.JDBCAttrRepoConf","sql":"SELECT * FROM table WHERE name=?","dialect":"org.hibernate.dialect.H2Dialect","driverClass":"org.h2.Driver","url":"jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1","user":"username","password":"password","singleRow":true,"requireAllAttributes":true,"caseCanonicalization":"NONE","queryType":"AND","columnMappings":{},"username":[],"attributes":{},"caseInsensitiveQueryAttributes [...]
   <AttrRepo id="DefaultStubAttrRepo" attrRepoState="ACTIVE"
-            description="Stub attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.StubAttrRepoConf","attributes":{"attr1":"value1"}}'/>
+            description="Stub attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.StubAttrRepoConf","attributes":{"attr1":"value1"}}'
+            items='[{"intAttrName":"attr1","extAttrName":"identifier","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}]'/>
   <AttrRepo id="DefaultSyncopeAttrRepo" attrRepoState="ACTIVE"
             description="Syncope attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.SyncopeAttrRepoConf","domain":"Master","searchFilter":"username=={user}","basicAuthUsername":"admin","basicAuthPassword":"password","headers":{}}'/>
 
-  <AttrRepoItem id="d2d9e7be-d82b-4698-b0fb-67d480413049" extAttrName="identifier" intAttrName="attr1"
-                password="0" purpose="NONE" mandatoryCondition="false" connObjectKey="0" attrRepo_id="DefaultStubAttrRepo"/>
-
   <RelationshipType id="inclusion" description="Models the act that an object is included in another"/>
   <RelationshipType id="neighborhood" description="Models the act that an object is near another"/>
   
@@ -607,11 +586,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.soap"
                 connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
                 version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false [...]
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
 
   <ConnInstance id="5aa5b8be-7521-481a-9651-c557aea078c1" displayName="H2"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -619,13 +595,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
                 version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="5aa5b8be-7521-481a-9651-c557aea078c1" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
+                capabilities='["AUTHENTICATE","CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
 
   <ConnInstance id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" displayName="ConnInstance102"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -634,11 +605,8 @@ under the License.
                 connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
                 version="${connid.soap.version}"
                 connRequestTimeout="10"
-                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http:/ [...]
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http:/ [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
 
   <ConnInstance id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" displayName="ConnInstance103"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -654,12 +622,8 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.csvdir"
                 connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
                 version="${connid.csvdir.version}"
-                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lan [...]
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lan [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
     
   <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
                 bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
@@ -667,11 +631,8 @@ under the License.
                 location="${connid.location}"
                 connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
                 version="${connid.ldap.version}" 
-                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
   
   <ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2"
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
@@ -679,88 +640,84 @@ under the License.
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
                 version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" capability="SYNC"/>
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpM [...]
+                capabilities='["CREATE","UPDATE","SYNC","SEARCH"]'/>
   
   <ConnInstance id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" bundleName="net.tirasa.connid.bundles.db.table" 
                 adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
                 displayName="H2-testpull" version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Pull capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage" [...]
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Pull capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage" [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
   
   <ConnInstance id="a6d017fd-a705-4507-bb7c-6ab6a6745997" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
                 adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
                 displayName="Scripted SQL" version="${connid.database.version}"
-                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schem [...]
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/>
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${conf.directory}/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schem [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
   
   <ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest"
                 adminRealm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c"
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorname="net.tirasa.connid.bundles.rest.RESTConnector"
                 displayname="REST" version="${connid.rest.version}"
-                jsonconf="[{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScript&quot;,&quot;displayName&quot;:&quot;authenticateScript&quot;,&quot;helpMessage&quot;:&quot;authenticateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;contentType&quot;,&quot [...]
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SYNC"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="DELETE"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SEARCH"/>
-  <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="UPDATE"/>
+                jsonconf="[{&quot;schema&quot;:{&quot;name&quot;:&quot;authenticateScript&quot;,&quot;displayName&quot;:&quot;authenticateScript&quot;,&quot;helpMessage&quot;:&quot;authenticateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;contentType&quot;,&quot [...]
+                capabilities='["AUTHENTICATE","CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/>
 
   <ExternalResource id="ws-target-resource-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password [...]
   <ExternalResource id="ws-target-resource-2" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    pullPolicy_id="9454b0d7-2610-400a-be82-fc23cf553dd6"/>
+                    pullPolicy_id="9454b0d7-2610-400a-be82-fc23cf553dd6"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"pas [...]
   <ExternalResource id="ws-target-resource-timeout" connector_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1" createTraceLevel="FAILURES" deleteTraceLevel="NONE" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
-                    jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/services/provisioning"]}]'/>
+                    jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/services/provisioning"]}]'
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-list-mappings-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password [...]
   <ExternalResource id="ws-target-resource-list-mappings-2" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
   <ExternalResource id="ws-target-resource-delete" connector_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    propagationPriority="2" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"username","extAttrNam [...]
   <ExternalResource id="ws-target-resource-update" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password" [...]
   <ExternalResource id="resource-testdb" connector_id="5aa5b8be-7521-481a-9651-c557aea078c1"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password" [...]
   <ExternalResource id="resource-testdb2" connector_id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"pa [...]
   <ExternalResource id="resource-csv" connector_id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0"
                     pullPolicy_id="880f8553-069b-4aed-9930-2cd53873f544"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["csv","generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"id" [...]
   <ExternalResource id="ws-target-resource-update-resetsynctoken" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":"{\"value\":null}","ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"__PASSWORD__","connObjectKey": [...]
   <ExternalResource id="resource-ldap" connector_id="74141a3b-0762-4720-a4aa-fc3e374ef3ef"
                     randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0"
                     propagationPriority="1"
-                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"&#39;uid=&#39; + username + &#39;,ou=people,o=isp&#39;","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]} [...]
   <Implementation id="LDAPMembershipPropagationActions" type="PROPAGATION_ACTIONS" engine="JAVA"
                   body="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/>
   <ExternalResourcePropAction resource_id="resource-ldap" implementation_id="LDAPMembershipPropagationActions"/>
@@ -768,51 +725,49 @@ 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":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when  [...]
-  <OrgUnit id="599a59cf-9a23-4447-9a59-cf9a2334473a" connObjectLink="syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'"
-           objectClass="organizationalUnit" resource_id="resource-ldap-orgunit" ignoreCaseMatch="0"/>
-  <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"/>
+                    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  [...]
+                    orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, &#39;ou&#39;) + &#39;,o=isp&#39;","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandato [...]
   
   <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"
-                    passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"/>
+                    passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   
-  <!-- The following three resources have been added to verify the issue SYNCOPE-68 -->
   <ExternalResource id="ws-target-resource-nopropagation2" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-nopropagation3" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
   <ExternalResource id="ws-target-resource-nopropagation4" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/>
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrN [...]
                     
-  <!-- External resource for issue SYNCOPE-230 -->
   <ExternalResource id="resource-db-pull" connector_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
-                    enforceMandatoryCondition="0" overrideCapabilities="0"/>
+                    enforceMandatoryCondition="0" overrideCapabilities="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"SURNAME","connObjectKey":false,"password":fa [...]
                     
-  <!-- External resource for issue SYNCOPE-267 -->
   <ExternalResource id="resource-db-virattr" connector_id="be24b061-019d-4e3e-baf0-0a6d0a45cb9c"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
-                    enforceMandatoryCondition="0" overrideCapabilities="0"/>
+                    enforceMandatoryCondition="0" overrideCapabilities="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[{"intAttrName":"virtualdata","extAttrName":"USERNAME","connObjectKey":false [...]
 
   <ExternalResource id="resource-db-scripted" connector_id="a6d017fd-a705-4507-bb7c-6ab6a6745997"
                     randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL"
                     enforceMandatoryCondition="0" overrideCapabilities="0"
-                    propagationPolicy_id="89d322db-9878-420c-b49c-67be13df9a12"/>
+                    propagationPolicy_id="89d322db-9878-420c-b49c-67be13df9a12"
+                    provisions='[{"anyType":"PRINTER","objectClass":"__PRINTER__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"PRINTERNAME","connObjectKey":false,"password":false, [...]
 
   <ExternalResource id="rest-target-resource" connector_id="44c02549-19c3-483c-8025-4919c3283c37"
                     createTraceLevel="ALL" updateTraceLevel="ALL"  deleteTraceLevel="ALL" provisioningTraceLevel="ALL" 
                     enforceMandatoryCondition="1" overrideCapabilities="0"
-                    propagationPriority="0" randomPwdIfNotProvided="0"/>
+                    propagationPriority="0" randomPwdIfNotProvided="0"
+                    provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"firstname","extAttrName":"firstName","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false [...]
 
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <AccountPolicy_ExternalResource accountPolicy_id="20ab5a8c-4b0c-432c-b957-f7fb9784d9f7" resource_id="resource-testdb"/>
@@ -829,304 +784,19 @@ under the License.
   <SyncopeGroup_ExternalResource group_id="b8d38784-57e7-4595-859a-076222644b55" resource_id="ws-target-resource-nopropagation3"/>
   <SyncopeGroup_ExternalResource group_id="0626100b-a4ba-4e00-9971-86fad52a6216" resource_id="resource-csv"/>
   <SyncopeGroup_ExternalResource group_id="ba9ed509-b1f5-48ab-a334-c8530a6422dc" resource_id="resource-csv"/>
-     
-  <Provision ignoreCaseMatch="0" id="209ea85f-f964-49c7-a498-6c9c2baa3bd8" resource_id="ws-target-resource-1" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" provision_id="209ea85f-f964-49c7-a498-6c9c2baa3bd8"/>
-  <MappingItem id="96aad4e0-2678-4903-a52f-0a7d090a2863" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" extAttrName="userId"
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="7f55b09c-b573-41dc-a9eb-ccd80bd3ea7a" extAttrName="email" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               intAttrName="email" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="a9749641-0556-49e2-a519-9bec35a4e06e" extAttrName="surname" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="d118671c-2e3e-4aa3-a3dd-fde2ba4c4ded" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="PROPAGATION"/>
-  <MappingItem id="dca9de4f-9a5a-4280-8e9a-357e321ba7a5" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc" 
-               extAttrName="fullname" intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="471f0e2e-2bde-4442-9abf-0effb533f2ee" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="type" intAttrName="ctype" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="72324cda-a66c-4ffe-b6b6-1d9b6cee9bf2" mapping_id="bc0cf27b-16b7-4e83-a4b0-09af7ea4aacc"
-               extAttrName="name" intAttrName="firstname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="NONE"/>
-  
-  <Provision ignoreCaseMatch="0" id="41a53a00-0b35-4047-831a-d5238f74c7ba" resource_id="ws-target-resource-list-mappings-1" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99" provision_id="41a53a00-0b35-4047-831a-d5238f74c7ba"/>
-  <MappingItem id="6f8d7b42-44f4-4697-aff5-1736c4b01ee4" mapping_id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99"
-               extAttrName="email" intAttrName="email" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="8515e385-3bf1-4928-adc9-489dee65829a" extAttrName="surname"
-               mapping_id="bf8afa4a-1522-44b9-91d0-c7b035e4fd99"
-               intAttrName="surname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="09a65250-d9de-44b1-9412-11ed996d356d" resource_id="ws-target-resource-list-mappings-2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="b12c4fad-f0f1-406d-b143-f2d68ed28e3a" provision_id="09a65250-d9de-44b1-9412-11ed996d356d"/>
-  <MappingItem id="55a4cf7f-ac96-4e8b-931c-2d0eab6a6bca" mapping_id="b12c4fad-f0f1-406d-b143-f2d68ed28e3a"
-               extAttrName="userId" intAttrName="userId" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="3d75991b-caee-4993-8e46-afb13d1bfbd4" resource_id="ws-target-resource-2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="240a0291-f89d-4557-a547-2a3b9aad625b" provision_id="3d75991b-caee-4993-8e46-afb13d1bfbd4"/>
-  <MappingItem id="d5c4d467-cd18-4148-8195-015808b4b3e6" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               extAttrName="fullname" intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="370a8673-f3f7-4328-a9ce-acd946f687c5" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-  <MappingItem id="c8d1a47a-1846-47b8-9f68-30aa21e94dcc" extAttrName="type" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="ctype" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="f0a06b24-7d4d-480e-8188-e53045885569" extAttrName="surname" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="surname" mandatoryCondition="type == 'F'"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="adc3c628-27b3-4740-be01-2f83c210ace9" extAttrName="name" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="virtualdata" mandatoryCondition="type == 'F'"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="6972a78b-2570-45d9-bc0b-31d2f2f9c860" extAttrName="fullname" mapping_id="240a0291-f89d-4557-a547-2a3b9aad625b"
-               intAttrName="cn" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-    
-  <Provision ignoreCaseMatch="0" id="9ebc3237-49fa-4dce-9a4c-3070e931812f" resource_id="ws-target-resource-update" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d" provision_id="9ebc3237-49fa-4dce-9a4c-3070e931812f"/>
-  <MappingItem id="cc973ed6-d031-4790-adab-fc059ac0c818" extAttrName="email" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="email" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="7a72c812-1897-4db0-bed4-4e7e8ea51afe" extAttrName="userId" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="userId" mandatoryCondition="false"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="946a3c7f-6359-4ab7-8a5f-adb08bdb4b5b" extAttrName="test3" mapping_id="c17813c0-4e90-4118-bb28-cd36ad6d5a4d"
-               intAttrName="fullname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-    
-  <Provision ignoreCaseMatch="0" id="8680bc79-dfa1-4719-9886-1d582bf1124f" resource_id="ws-target-resource-nopropagation" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="63ddd4c8-efed-4a22-a4b4-1f4e6f47c8d0" provision_id="8680bc79-dfa1-4719-9886-1d582bf1124f"/>
-  <MappingItem id="ffcfbb5e-7bbd-489a-a69e-2dd84f00731a" mapping_id="63ddd4c8-efed-4a22-a4b4-1f4e6f47c8d0" extAttrName="fullname" 
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="0bfa7c3e-2bb3-43d7-ac0e-d57cff7a18c8" resource_id="ws-target-resource-nopropagation2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="3f636292-6edb-4d20-ab24-fe0c5fc3dec3" provision_id="0bfa7c3e-2bb3-43d7-ac0e-d57cff7a18c8"/>
-  <MappingItem id="e34928b8-ca57-4b6c-81c1-70bc87ff3fdc" mapping_id="3f636292-6edb-4d20-ab24-fe0c5fc3dec3" extAttrName="fullname" 
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="5bd76fec-f8d7-4ab9-acd7-89e099d534e8" resource_id="ws-target-resource-nopropagation3" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c2a0cec1-32c4-4493-8f01-d1176e557fc1" provision_id="5bd76fec-f8d7-4ab9-acd7-89e099d534e8"/>
-  <MappingItem id="f3ba0859-b0f0-44a5-abfd-4a1a5ca29fbf" mapping_id="c2a0cec1-32c4-4493-8f01-d1176e557fc1" extAttrName="fullname"
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                     
-  <Provision ignoreCaseMatch="0" id="18de6376-7051-4216-96f0-26629076abb9" resource_id="ws-target-resource-nopropagation4" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="906452d9-3eeb-4ef7-ac90-5ffc14513fbf" provision_id="18de6376-7051-4216-96f0-26629076abb9"/>
-  <MappingItem id="118" mapping_id="906452d9-3eeb-4ef7-ac90-5ffc14513fbf"
-               extAttrName="fullname" intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-                       
-  <Provision ignoreCaseMatch="0" id="779fefb5-dd25-4078-915d-3c199ee32158" resource_id="resource-testdb" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="cb624b93-874b-40a0-8021-3b8116b781ab" provision_id="779fefb5-dd25-4078-915d-3c199ee32158"/>
-  <MappingItem id="1e0d30cd-2569-4a80-b9dc-af1467bd1c0b" mapping_id="cb624b93-874b-40a0-8021-3b8116b781ab"
-               extAttrName="ID" intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="7fd1a178-77a1-4c4c-aca2-3c3f1834b77b" mapping_id="cb624b93-874b-40a0-8021-3b8116b781ab"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-                     
-  <Provision ignoreCaseMatch="0" id="0359084d-68fe-4bf8-b42b-2ebe4f578ae7" resource_id="resource-testdb2" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" provision_id="0359084d-68fe-4bf8-b42b-2ebe4f578ae7"/>
-  <MappingItem id="6d90658a-f470-4450-912d-6fe7d3bcda46" mapping_id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" extAttrName="ID" 
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="2fb9eb01-50df-456e-86c1-b55f68cde2da" mapping_id="935a0fc2-4a0b-4d82-9931-3c5ce44a33c1" extAttrName="__PASSWORD__" 
-               intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="PROPAGATION"/>
-                         
-  <Provision ignoreCaseMatch="0" id="2adb6537-e207-4d9b-804f-90bf18cd6f48" resource_id="resource-csv" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="csv"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="generic membership"/>
-  <Provision_AnyTypeClass provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48" anyTypeClass_id="minimal group"/>
-  <Mapping id="538c27dc-d260-4c53-9fc8-bf02ee226911" provision_id="2adb6537-e207-4d9b-804f-90bf18cd6f48"/>
-  <MappingItem id="517dc983-99a2-43c9-b4b4-78fd838e5ad1" extAttrName="id" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="ba6fb125-466e-4109-8e5d-133936437674" extAttrName="id" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="fullname" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="c426b070-0290-42be-9ee1-4046c7649635" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-  <MappingItem id="20dbe358-5b71-4edd-8670-2bbde982e5c4" extAttrName="name" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="firstname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="4d70850e-9fc5-4e75-83ea-432fe090e1c0" extAttrName="surname" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="surname" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="4b2f4292-d8ab-4948-a341-3f8c9e23e72d" extAttrName="email" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="userId" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PULL"/>
-  <MappingItem id="20d6c914-54e7-4968-b1fc-685ae9c2c4a4" extAttrName="email" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="email" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="PULL"/>
-  <MappingItem id="09237f39-0d45-4258-a7cc-2400f7536b72" extAttrName="__NAME__" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="csvuserid" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  <MappingItem id="63151b89-2eb3-4980-a682-0215d54ab4a2" extAttrName="theirgroup" mapping_id="538c27dc-d260-4c53-9fc8-bf02ee226911"
-               intAttrName="groups[root].rderToBePropagated" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="PROPAGATION"/>
-                         
-  <Provision ignoreCaseMatch="0" id="1b53c74e-6a63-49ef-b2f1-96eeb7f1bbb8" resource_id="ws-target-resource-update-resetsynctoken" anyType_id="USER" objectClass="__ACCOUNT__"
-             serializedSyncToken='{"value":null}'/>
-  <Mapping id="23e20ce6-1ff9-495e-aa59-a58e5127a008" provision_id="1b53c74e-6a63-49ef-b2f1-96eeb7f1bbb8"/>
-  <MappingItem id="608f01c5-eb7c-462a-b4d6-b7c3c9632a50" mapping_id="23e20ce6-1ff9-495e-aa59-a58e5127a008"
-               extAttrName="userId" intAttrName="userId" mandatoryCondition="false"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="79ada054-5f8b-4e77-b405-bfec58b06e7b" mapping_id="23e20ce6-1ff9-495e-aa59-a58e5127a008"
-               extAttrName="__PASSWORD__" intAttrName="fullname" mandatoryCondition="false"
-               connObjectKey="0" password="1" purpose="BOTH"/>
-
-  <Provision ignoreCaseMatch="0" id="8b938d63-aa92-448c-89a8-a685fc0a67c8" resource_id="resource-ldap" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Provision_AnyTypeClass provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" anyTypeClass_id="generic membership"/>
-  <Provision_AnyTypeClass provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" anyTypeClass_id="minimal group"/>
-  <Mapping id="ae1c77c3-2f1d-4258-ad06-710bb09041a9" provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8"
-           connObjectLink="&apos;uid=&apos; + username + &apos;,ou=people,o=isp&apos;"/>
-  <MappingItem id="9ff7d686-452c-4cec-a475-c1137c5d88c7" connObjectKey="1" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="cn" intAttrName="username"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="73d97083-cfda-44e6-be62-3f9ac558b5eb" connObjectKey="0" password="1" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="__PASSWORD__" intAttrName="password"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="cf0a222c-36ea-41e6-987c-7908614ccd23" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="sn" intAttrName="surname"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="b3a12364-e471-4e37-83ad-476c33a43617" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="cn" intAttrName="fullname"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="aad2b7d7-3201-4bba-b496-f6587b4b7518" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="mail" intAttrName="email"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="81b83c98-127b-469b-a497-412ba50acbeb" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="title" intAttrName="title"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="318e92a1-3acb-49c5-b2fd-dba819c40ef1" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="postalAddress" intAttrName="postalAddress"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="78fa504f-213c-41ac-a922-7c9f98e5ce11" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="mail" intAttrName="userId"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="af6085cb-d0e8-47c9-b5f9-4b7d491a9750" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="registeredAddress" intAttrName="obscure"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="5bb62bd2-5007-4eb8-b4f9-9df8917dc767" connObjectKey="0" password="0" mapping_id="ae1c77c3-2f1d-4258-ad06-710bb09041a9"
-               extAttrName="jpegPhoto" intAttrName="photo"
-               mandatoryCondition="false" purpose="BOTH"/>
         
   <SyncopeSchema id="virtualReadOnly"/>
   <VirSchema id="virtualReadOnly" READONLY="1" anyTypeClass_id="minimal user"
-             provision_id="8b938d63-aa92-448c-89a8-a685fc0a67c8" extAttrName="givenname"/>
-
-  <Provision ignoreCaseMatch="0" id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d" resource_id="resource-ldap" anyType_id="GROUP" objectClass="__GROUP__"/>
-  <Mapping id="128412c8-be4f-4d7b-8bed-5ab89134f718" provision_id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d"
-           connObjectLink="&apos;cn=&apos; + name + &apos;,ou=groups,o=isp&apos;"/>
-  <MappingItem id="a2bf43c8-74cb-4250-92cf-fb8889409ac1"
-               connObjectKey="1" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="cn" intAttrName="name"
-               mandatoryCondition="true" purpose="BOTH"/>
-  <MappingItem id="da2a69bc-5ca0-4657-9a18-ec1f8c986046"
-               connObjectKey="0" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="owner" intAttrName="userOwner"
-               mandatoryCondition="false" purpose="BOTH"/>
-  <MappingItem id="9dde8bd5-f158-499e-9d81-3d7fcf9ea1e8"
-               connObjectKey="0" password="0" mapping_id="128412c8-be4f-4d7b-8bed-5ab89134f718"
-               extAttrName="description" intAttrName="title"
-               mandatoryCondition="false" purpose="BOTH"/>
+             resource_id="resource-ldap" anyType_id="USER" extAttrName="givenname"/>
   
   <SyncopeSchema id="rvirtualdata"/>
   <VirSchema id="rvirtualdata" READONLY="0" anyTypeClass_id="minimal group"
-             provision_id="20a75199-3f2e-4b9a-9510-c68dd7fc7b3d" extAttrName="businessCategory"/>
-
-  <Provision ignoreCaseMatch="0" id="46b54e2a-e43e-4cd7-8c13-1af1bd65c3d3" resource_id="resource-db-pull" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="cda910bd-fc28-4f63-890e-66edc62d428b" provision_id="46b54e2a-e43e-4cd7-8c13-1af1bd65c3d3"/>
-  <MappingItem id="1a345706-a498-41bb-a948-820307a4365e" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="EMAIL" intAttrName="email" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="a234bde8-b431-408c-8ec9-c986c5b7f98d" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="SURNAME" intAttrName="fullname" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-  <MappingItem id="51a856de-ae25-41cd-967a-86920c834b70" connObjectKey="1" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="ID" intAttrName="firstname" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="f4e5178e-ef37-4949-933a-7ec7eaea64c6" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="SURNAME" intAttrName="surname" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="3ac0ecaf-d9a1-4fc1-9ae9-84dc34576810" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="USERNAME" intAttrName="username" 
-               mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <MappingItem id="e7215305-93c9-460b-b862-46f7b60de72d" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="EMAIL" intAttrName="userId" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-  <MappingItem id="fb59d169-cf59-43f6-a517-adfd9aacc609" connObjectKey="0" mapping_id="cda910bd-fc28-4f63-890e-66edc62d428b"
-               extAttrName="MUSTCHANGEPASSWORD" intAttrName="mustChangePassword" 
-               mandatoryCondition="false" password="0" purpose="PULL"/>
-              
-  <Provision ignoreCaseMatch="0" id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930" resource_id="resource-db-virattr" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="45280585-308f-4571-9788-c7a4734b3614" provision_id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930"/>
-  <MappingItem id="6cb2f9f0-5fb4-4686-a375-31e2c34a6cd8" mapping_id="45280585-308f-4571-9788-c7a4734b3614" connObjectKey="1" password="0"
-               extAttrName="ID" intAttrName="key" 
-               mandatoryCondition="true" purpose="BOTH"/>
-                
+             resource_id="resource-ldap" anyType_id="GROUP" extAttrName="businessCategory"/>
+
   <SyncopeSchema id="virtualdata"/>
   <VirSchema id="virtualdata" READONLY="0" anyTypeClass_id="minimal user"
-             provision_id="6d7cb60a-c4ad-4a70-94ae-e5b88eb24930" extAttrName="USERNAME"/>
+             resource_id="resource-db-virattr" anyType_id="USER" extAttrName="USERNAME"/>
   
-  <Provision ignoreCaseMatch="0" id="cfa86cbe-94b6-4712-a40a-a4861be1d425" resource_id="ws-target-resource-timeout" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="c71d690a-3dd9-48a5-b76f-32805186c4dc" provision_id="cfa86cbe-94b6-4712-a40a-a4861be1d425"/>
-  <MappingItem id="321bc904-e1fc-4a54-bf7c-74c8cbcc0815" mapping_id="c71d690a-3dd9-48a5-b76f-32805186c4dc" connObjectKey="1" password="0"
-               extAttrName="fullname" intAttrName="fullname"
-               mandatoryCondition="true" purpose="PROPAGATION"/>
-  
-  <Provision ignoreCaseMatch="0" id="ac1659dc-3ea3-45eb-8ae6-626e3d916492" resource_id="ws-target-resource-delete" anyType_id="USER" objectClass="__ACCOUNT__"/>
-  <Mapping id="72f590ae-2754-456b-aabb-eda7d8459dd3" provision_id="ac1659dc-3ea3-45eb-8ae6-626e3d916492"/>
-  <MappingItem id="4c98536f-10df-4953-b2df-59d7cd057fd2" mapping_id="72f590ae-2754-456b-aabb-eda7d8459dd3" extAttrName="userId" 
-               intAttrName="username" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="PROPAGATION"/>
-
-  <Provision ignoreCaseMatch="0" id="f1b55b66-eb13-4a93-a49c-448e93756eb6" resource_id="resource-db-scripted" anyType_id="PRINTER" objectClass="__PRINTER__"/>
-  <Mapping id="16439b5f-50c3-4604-97e9-f4004933abd8" provision_id="f1b55b66-eb13-4a93-a49c-448e93756eb6"/>
-  <MappingItem id="23aa0299-ddbb-4e59-8918-0ab2a32465fa" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="ID" 
-               intAttrName="key" mandatoryCondition="true"
-               connObjectKey="1" password="0" purpose="BOTH"/>
-  <MappingItem id="3dc96af0-5d0a-4ec1-be84-244716d88401" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="PRINTERNAME" 
-               intAttrName="name" mandatoryCondition="true"
-               connObjectKey="0" password="0" purpose="BOTH"/>
-  <MappingItem id="f3ef9f8b-e667-4b18-969f-ba98c3d78bc0" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="LOCATION" 
-               intAttrName="location"
-               mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
-    
-  <Provision ignoreCaseMatch="0" id="2e372858-f43c-4e1c-b728-58f43c5e1c23" objectClass="__ACCOUNT__" anyType_id="USER" resource_id="rest-target-resource"/>
-  <Mapping id="e6b64584-94a2-4890-b645-8494a2089011" provision_id="2e372858-f43c-4e1c-b728-58f43c5e1c23"/>
-  <MappingItem id="14726efb-09e1-441e-b26e-fb09e1841eb2" connObjectKey="0"
-               extAttrName="firstName" intAttrName="firstname" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="4cdd1fd5-80cd-4fc1-9d1f-d580cd1fc11e" connObjectKey="1"
-               extAttrName="key" intAttrName="key" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="4d7581b5-fe9b-49e6-b581-b5fe9bf9e60b" connObjectKey="0"
-               extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true" password="1" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="98f96cf4-fba2-4c68-b96c-f4fba2fc6834" connObjectKey="0"
-               extAttrName="username" intAttrName="username" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="f3312f8f-1c94-493a-b12f-8f1c94093aa9" connObjectKey="0"
-               extAttrName="email" intAttrName="email" mandatoryCondition="true" password="0" purpose="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-  <MappingItem id="ff49e982-fe60-4c1e-89e9-82fe60dc1ef9" connObjectKey="0"
-               extAttrName="surname" intAttrName="surname" mandatoryCondition="true" password="0" PURPOSE="BOTH"
-               mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/>
-
   <Implementation id="PullJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
                   body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/>
   <Implementation id="PushJobDelegate" type="TASKJOB_DELEGATE" engine="JAVA"
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
index 5d5db89062..68ac4bda91 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -99,10 +99,7 @@ we are happy to inform you that the password request was successfully executed f
                 location="${connid.location}"
                 connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
                 version="${connid.ldap.version}" 
-                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
-  <ConnInstance_capabilities connInstance_id="b7ea96c3-c633-488b-98a0-b52ac35850f7" capability="CREATE"/>
-  <ConnInstance_capabilities connInstance_id="b7ea96c3-c633-488b-98a0-b52ac35850f7" capability="UPDATE"/>
-  <ConnInstance_capabilities connInstance_id="b7ea96c3-c633-488b-98a0-b52ac35850f7" capability="DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="b7ea96c3-c633-488b-98a0-b52ac35850f7" capability="SEARCH"/>
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership" [...]
+                capabilities='["CREATE","UPDATE","DELETE","SEARCH"]'/>
   
 </dataset>
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorManager.java
index 5a51923463..080bb41afe 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorManager.java
@@ -24,7 +24,7 @@ import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 
 /**
  * Entry point for creating and destroying connectors for external resources.
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 df6c43ffa3..e25d893136 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
@@ -23,14 +23,15 @@ import java.util.Optional;
 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.Item;
+import org.apache.syncope.common.lib.to.OrgUnit;
+import org.apache.syncope.common.lib.to.Provision;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 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.Item;
-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.persistence.api.entity.user.LinkedAccount;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.identityconnectors.framework.common.objects.Attribute;
@@ -41,10 +42,11 @@ public interface MappingManager {
      * Get connObjectKey internal value.
      *
      * @param any any object
+     * @param resource resource information
      * @param provision provision information
      * @return connObjectKey internal value
      */
-    Optional<String> getConnObjectKeyValue(Any<?> any, Provision provision);
+    Optional<String> getConnObjectKeyValue(Any<?> any, ExternalResource resource, Provision provision);
 
     /**
      * Get connObjectKey internal value.
@@ -58,6 +60,7 @@ public interface MappingManager {
     /**
      * Get attribute values for the given {@link Item} and any object.
      *
+     * @param resource resource information
      * @param provision provision information
      * @param mapItem mapping item
      * @param intAttrName int attr name
@@ -68,6 +71,7 @@ public interface MappingManager {
      * @return attribute values and their type
      */
     Pair<AttrSchemaType, List<PlainAttrValue>> getIntValues(
+            ExternalResource resource,
             Provision provision,
             Item mapItem,
             IntAttrName intAttrName,
@@ -79,6 +83,7 @@ public interface MappingManager {
     /**
      * Prepare attribute for sending to a connector instance.
      *
+     * @param resource resource information
      * @param provision provision information
      * @param item mapping item
      * @param any given any object
@@ -89,8 +94,10 @@ public interface MappingManager {
      * @return connObjectLink (if it is the case) + prepared attribute
      */
     Pair<String, Attribute> prepareAttr(
+            ExternalResource resource,
             Provision provision,
-            Item item, Any<?> any,
+            Item item,
+            Any<?> any,
             String password,
             AccountGetter usernameAccountGetter,
             AccountGetter passwordAccountGetter,
@@ -103,11 +110,17 @@ public interface MappingManager {
      * @param password clear-text password
      * @param changePwd whether password should be included for propagation attributes or not
      * @param enable whether any object must be enabled or not
+     * @param resource resource information
      * @param provision provision information
      * @return connObjectLink + prepared attributes
      */
     Pair<String, Set<Attribute>> prepareAttrsFromAny(
-            Any<?> any, String password, boolean changePwd, Boolean enable, Provision provision);
+            Any<?> any,
+            String password,
+            boolean changePwd,
+            Boolean enable,
+            ExternalResource resource,
+            Provision provision);
 
     /**
      * Prepare attributes for sending to a connector instance.
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java
index a4207c54a5..7cbba896e0 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java
@@ -19,9 +19,8 @@
 package org.apache.syncope.core.provisioning.api;
 
... 8207 lines suppressed ...