You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/05/25 16:50:37 UTC

[01/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Repository: syncope
Updated Branches:
  refs/heads/SYNCOPE-666 [created] 081d9a04a


http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 43f0ffb..9c67d13 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -44,11 +44,10 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.AttributableOperations;
+import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
@@ -66,13 +65,13 @@ import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -312,8 +311,8 @@ public class UserITCase extends AbstractITCase {
         // configured to be minLength=16
         userTO.setPassword("password1");
 
-        final MembershipTO membership = new MembershipTO();
-        membership.setGroupKey(8L);
+        MembershipTO membership = new MembershipTO();
+        membership.setRightKey(8L);
 
         userTO.getMemberships().add(membership);
 
@@ -346,12 +345,9 @@ public class UserITCase extends AbstractITCase {
 
         // add a membership
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
-        // add an attribute with no values: must be ignored
-        membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", null));
-
         // add an attribute with a non-existing schema: must be ignored
         AttrTO attrWithInvalidSchemaTO = attrTO("invalid schema", "a value");
         userTO.getPlainAttrs().add(attrWithInvalidSchemaTO);
@@ -445,7 +441,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getPlainAttrs().remove(type);
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user without type (mandatory by UserSchema)
@@ -637,8 +633,7 @@ public class UserITCase extends AbstractITCase {
         UserTO userTO = getUniqueSampleTO("g.h@t.com");
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
-        membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", "2009-08-18T16:33:12.203+0200"));
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
@@ -646,10 +641,6 @@ public class UserITCase extends AbstractITCase {
         assertFalse(userTO.getDerAttrs().isEmpty());
         assertEquals(1, userTO.getMemberships().size());
 
-        MembershipMod membershipMod = new MembershipMod();
-        membershipMod.setGroup(8L);
-        membershipMod.getPlainAttrsToUpdate().add(attrMod("subscriptionDate", "2010-08-18T16:33:12.203+0200"));
-
         UserMod userMod = new UserMod();
         userMod.setKey(userTO.getKey());
         userMod.setPassword("new2Password");
@@ -663,7 +654,7 @@ public class UserITCase extends AbstractITCase {
         userMod.getPlainAttrsToUpdate().add(attrMod("fullname", newFullName));
 
         userMod.getDerAttrsToAdd().add("cn");
-        userMod.getMembershipsToAdd().add(membershipMod);
+        userMod.getMembershipsToAdd().add(8L);
         userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
 
         userTO = updateUser(userMod);
@@ -677,7 +668,6 @@ public class UserITCase extends AbstractITCase {
         assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
 
         assertEquals(1, userTO.getMemberships().size());
-        assertEquals(1, userTO.getMemberships().iterator().next().getPlainAttrs().size());
         assertFalse(userTO.getDerAttrs().isEmpty());
 
         AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
@@ -695,8 +685,7 @@ public class UserITCase extends AbstractITCase {
 
         UserTO userTO = getUniqueSampleTO("pwdonly@t.com");
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
-        membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", "2009-08-18T16:33:12.203+0200"));
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
@@ -736,7 +725,7 @@ public class UserITCase extends AbstractITCase {
 
         // add a membership
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user
@@ -811,7 +800,7 @@ public class UserITCase extends AbstractITCase {
         UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(11L);
+        membershipTO.setRightKey(11L);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
@@ -838,7 +827,7 @@ public class UserITCase extends AbstractITCase {
         UserTO userTO = getUniqueSampleTO("suspendReactivate@syncope.apache.org");
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7L);
+        membershipTO.setRightKey(7L);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
@@ -892,10 +881,11 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
         assertEquals("suspended", userTO.getStatus());
 
-        ConnObjectTO connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
         assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userId);
         assertNotNull(connObjectTO);
 
         // Suspend and reactivate only on ldap => db and syncope should still show suspended
@@ -909,7 +899,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
         assertEquals("suspended", userTO.getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
         assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
 
         // Reactivate on syncope and db => syncope and db should show the user as active
@@ -922,7 +912,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
         assertEquals("active", userTO.getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userId);
         assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
     }
 
@@ -1019,7 +1009,7 @@ public class UserITCase extends AbstractITCase {
         toBeUpdated.getVirAttrs().add(virtual);
 
         // 2. try to update by adding a resource, but no password: must fail
-        UserMod userMod = AttributableOperations.diff(toBeUpdated, original);
+        UserMod userMod = AnyOperations.diff(toBeUpdated, original);
         assertNotNull(userMod);
 
         toBeUpdated = updateUser(userMod);
@@ -1115,7 +1105,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(1L);
+        membershipTO.setRightKey(1L);
 
         userTO.getMemberships().add(membershipTO);
 
@@ -1126,40 +1116,12 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual.getDerAttrMap().get("csvuserid"));
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
         assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("THEIRGROUP").getValues().get(0));
     }
 
     @Test
-    public void membershipAttrPropagation() {
-        UserTO userTO = getUniqueSampleTO("checkMembAttrPropagation@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(1L);
-        membershipTO.getPlainAttrs().add(attrTO("mderived_sx", "sx"));
-        membershipTO.getPlainAttrs().add(attrTO("mderived_dx", "dx"));
-        membershipTO.getDerAttrs().add(attrTO("mderToBePropagated", null));
-        userTO.getMemberships().add(membershipTO);
-
-        userTO.getResources().add(RESOURCE_NAME_CSV);
-
-        UserTO actual = createUser(userTO);
-        assertNotNull(actual);
-        assertNotNull(actual.getDerAttrMap().get("csvuserid"));
-
-        ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
-        assertNotNull(connObjectTO);
-        assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("MEMBERSHIP").getValues().get(0));
-    }
-
-    @Test
     public void noContent() throws IOException {
         SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
         UserService noContentService = noContentclient.prefer(UserService.class, Preference.RETURN_NO_CONTENT);
@@ -1198,12 +1160,12 @@ public class UserITCase extends AbstractITCase {
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         MembershipTO memb12 = new MembershipTO();
-        memb12.setGroupKey(12L);
+        memb12.setRightKey(12L);
 
         userTO.getMemberships().add(memb12);
 
         MembershipTO memb13 = new MembershipTO();
-        memb13.setGroupKey(13L);
+        memb13.setRightKey(13L);
 
         userTO.getMemberships().add(memb13);
 
@@ -1215,7 +1177,7 @@ public class UserITCase extends AbstractITCase {
         assertEquals(1, actual.getResources().size());
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
 
         // -----------------------------------
@@ -1230,7 +1192,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertEquals(1, actual.getMemberships().size());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
         // -----------------------------------
 
@@ -1247,7 +1209,7 @@ public class UserITCase extends AbstractITCase {
         assertEquals(1, actual.getMemberships().size());
         assertFalse(actual.getResources().isEmpty());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
         // -----------------------------------
 
@@ -1265,7 +1227,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail("Read should not succeeed");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -1273,74 +1235,6 @@ public class UserITCase extends AbstractITCase {
     }
 
     @Test
-    public void issueSYNCOPE111() {
-        UserTO userTO = getUniqueSampleTO("syncope111@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getMemberships().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getVirAttrs().clear();
-        userTO.getDerAttrs().add(attrTO("csvuserid", null));
-
-        MembershipTO memb12 = new MembershipTO();
-        memb12.setGroupKey(12L);
-        memb12.getPlainAttrs().add(attrTO("postalAddress", "postalAddress"));
-        userTO.getMemberships().add(memb12);
-
-        MembershipTO memb13 = new MembershipTO();
-        memb13.setGroupKey(13L);
-        userTO.getMemberships().add(memb13);
-
-        userTO.getResources().add(RESOURCE_NAME_LDAP);
-
-        UserTO actual = createUser(userTO);
-        assertNotNull(actual);
-        assertEquals(2, actual.getMemberships().size());
-
-        ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
-        assertNotNull(connObjectTO);
-
-        AttrTO postalAddress = connObjectTO.getPlainAttrMap().get("postalAddress");
-        assertNotNull(postalAddress);
-        assertEquals(1, postalAddress.getValues().size());
-        assertEquals("postalAddress", postalAddress.getValues().get(0));
-
-        AttrTO title = connObjectTO.getPlainAttrMap().get("title");
-        assertNotNull(title);
-        assertEquals(2, title.getValues().size());
-        assertTrue(title.getValues().contains("r12") && title.getValues().contains("r13"));
-
-        // -----------------------------------
-        // Remove the first membership and check for membership attr propagation and group attr propagation
-        // -----------------------------------
-        UserMod userMod = new UserMod();
-        userMod.setKey(actual.getKey());
-
-        MembershipTO membershipTO = actual.getMemberships().get(0).getGroupKey() == 12L
-                ? actual.getMemberships().get(0)
-                : actual.getMemberships().get(1);
-
-        userMod.getMembershipsToRemove().add(membershipTO.getKey());
-
-        actual = updateUser(userMod);
-        assertNotNull(actual);
-        assertEquals(1, actual.getMemberships().size());
-
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
-        assertNotNull(connObjectTO);
-
-        postalAddress = connObjectTO.getPlainAttrMap().get("postalAddress");
-        assertTrue(postalAddress == null || postalAddress.getValues().isEmpty()
-                || StringUtils.isNotBlank(postalAddress.getValues().get(0)));
-
-        title = connObjectTO.getPlainAttrMap().get("title");
-        assertNotNull(title);
-        assertEquals(1, title.getValues().size());
-        assertTrue(title.getValues().contains("r13"));
-        // -----------------------------------
-    }
-
-    @Test
     public void issueSYNCOPE185() {
         // 1. create user with LDAP resource, succesfully propagated
         UserTO userTO = getSampleTO("syncope185@syncope.apache.org");
@@ -1358,7 +1252,7 @@ public class UserITCase extends AbstractITCase {
 
         // 3. try (and fail) to find this user on the external LDAP resource
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
             fail("This entry should not be present on this resource");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -1409,7 +1303,7 @@ public class UserITCase extends AbstractITCase {
         assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_DBVIRATTR, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("USERNAME").getValues().get(0));
         // ----------------------------------
@@ -1466,16 +1360,16 @@ public class UserITCase extends AbstractITCase {
 
         final String pwdOnSyncope = userTO.getPassword();
 
-        ConnObjectTO userOnDb = resourceService.getConnectorObject(
-                RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+        ConnObjectTO userOnDb = resourceService.readConnObject(
+                RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
         final AttrTO pwdOnTestDbAttr = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
         assertNotNull(pwdOnTestDbAttr);
         assertNotNull(pwdOnTestDbAttr.getValues());
         assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
         final String pwdOnTestDb = pwdOnTestDbAttr.getValues().iterator().next();
 
-        ConnObjectTO userOnDb2 = resourceService.getConnectorObject(
-                RESOURCE_NAME_TESTDB2, SubjectType.USER, userTO.getKey());
+        ConnObjectTO userOnDb2 = resourceService.readConnObject(
+                RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
         final AttrTO pwdOnTestDb2Attr = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
         assertNotNull(pwdOnTestDb2Attr);
         assertNotNull(pwdOnTestDb2Attr.getValues());
@@ -1502,7 +1396,7 @@ public class UserITCase extends AbstractITCase {
         assertEquals(pwdOnSyncope, userTO.getPassword());
 
         // 3c. verify that password *has* changed on testdb
-        userOnDb = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+        userOnDb = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
         final AttrTO pwdOnTestDbAttrAfter = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
         assertNotNull(pwdOnTestDbAttrAfter);
         assertNotNull(pwdOnTestDbAttrAfter.getValues());
@@ -1510,7 +1404,7 @@ public class UserITCase extends AbstractITCase {
         assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().iterator().next());
 
         // 3d. verify that password hasn't changed on testdb2
-        userOnDb2 = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB2, SubjectType.USER, userTO.getKey());
+        userOnDb2 = resourceService.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
         final AttrTO pwdOnTestDb2AttrAfter = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
         assertNotNull(pwdOnTestDb2AttrAfter);
         assertNotNull(pwdOnTestDb2AttrAfter.getValues());
@@ -1608,7 +1502,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
         assertNull(connObjectTO.getPlainAttrMap().get("email"));
     }
 
@@ -1668,7 +1562,7 @@ public class UserITCase extends AbstractITCase {
     public void issueSYNCOPE354() {
         // change resource-ldap group mapping for including uniqueMember (need for assertions below)
         ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
-        for (MappingItemTO item : ldap.getGmapping().getItems()) {
+        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("description".equals(item.getExtAttrName())) {
                 item.setExtAttrName("uniqueMember");
             }
@@ -1688,15 +1582,15 @@ public class UserITCase extends AbstractITCase {
         UserTO userTO = getUniqueSampleTO("syncope354@syncope.apache.org");
         userTO.getResources().add(RESOURCE_NAME_LDAP);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(groupTO.getKey());
+        membershipTO.setRightKey(groupTO.getKey());
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
         assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
 
         // 3. read group on resource, check that user DN is included in uniqueMember
-        ConnObjectTO connObj = resourceService.getConnectorObject(
-                RESOURCE_NAME_LDAP, SubjectType.GROUP, groupTO.getKey());
+        ConnObjectTO connObj = resourceService.readConnObject(
+                RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
         assertNotNull(connObj);
         assertTrue(connObj.getPlainAttrMap().get("uniqueMember").getValues().
                 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
@@ -1710,13 +1604,13 @@ public class UserITCase extends AbstractITCase {
         assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
 
         // 5. read group on resource, check that user DN was removed from uniqueMember
-        connObj = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, groupTO.getKey());
+        connObj = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
         assertNotNull(connObj);
         assertFalse(connObj.getPlainAttrMap().get("uniqueMember").getValues().
                 contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
 
         // 6. restore original resource-ldap group mapping
-        for (MappingItemTO item : ldap.getGmapping().getItems()) {
+        for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
             if ("uniqueMember".equals(item.getExtAttrName())) {
                 item.setExtAttrName("description");
             }
@@ -1741,7 +1635,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getPlainAttrs().add(attrTO("photo",
                 Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(groupTO.getKey());
+        membershipTO.setRightKey(groupTO.getKey());
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
@@ -1750,8 +1644,8 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO.getPlainAttrMap().get("photo"));
 
         // 3. read user on resource
-        ConnObjectTO connObj = resourceService.getConnectorObject(
-                RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+        ConnObjectTO connObj = resourceService.readConnObject(
+                RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObj);
         AttrTO registeredAddress = connObj.getPlainAttrMap().get("registeredAddress");
         assertNotNull(registeredAddress);
@@ -1765,7 +1659,7 @@ public class UserITCase extends AbstractITCase {
 
         // 5. try to read user on resource: fail
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -1857,7 +1751,7 @@ public class UserITCase extends AbstractITCase {
 
         UserTO actual = createUser(userTO);
         assertNotNull(actual);
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
@@ -1868,7 +1762,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertTrue(actual.getResources().isEmpty());
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
     }
 
     @Test
@@ -1885,7 +1779,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -1902,7 +1796,7 @@ public class UserITCase extends AbstractITCase {
         assertFalse(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -1921,7 +1815,7 @@ public class UserITCase extends AbstractITCase {
 
         UserTO actual = createUser(userTO);
         assertNotNull(actual);
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
@@ -1933,7 +1827,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -1954,7 +1848,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -1971,7 +1865,7 @@ public class UserITCase extends AbstractITCase {
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
         assertFalse(actual.getResources().isEmpty());
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
     }
 
     @Test
@@ -1986,7 +1880,7 @@ public class UserITCase extends AbstractITCase {
 
         UserTO actual = createUser(userTO);
         assertNotNull(actual);
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
@@ -1998,7 +1892,7 @@ public class UserITCase extends AbstractITCase {
         assertFalse(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -2019,7 +1913,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -2037,7 +1931,7 @@ public class UserITCase extends AbstractITCase {
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
         assertTrue(actual.getResources().isEmpty());
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
     }
 
     @Test
@@ -2054,7 +1948,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -2072,7 +1966,7 @@ public class UserITCase extends AbstractITCase {
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
         assertTrue(actual.getResources().isEmpty());
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
@@ -2084,7 +1978,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -2181,7 +2075,7 @@ public class UserITCase extends AbstractITCase {
 
         // 2. read resource configuration for LDAP binding
         ConnObjectTO connObject =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
 
         // 3. try (and succeed) to perform simple LDAP binding with provided password ('password123')
         assertNotNull(getLdapRemoteObject(
@@ -2214,8 +2108,8 @@ public class UserITCase extends AbstractITCase {
         assertEquals(1, userTO.getPropagationStatusTOs().size());
         assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
 
-        final ConnObjectTO actual = resourceService.getConnectorObject(RESOURCE_NAME_WS1, SubjectType.USER, userTO.
-                getKey());
+        ConnObjectTO actual =
+                resourceService.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(actual);
         // check if mapping attribute with purpose NONE really hasn't been propagated
         assertNull(actual.getPlainAttrMap().get("NAME"));
@@ -2224,7 +2118,7 @@ public class UserITCase extends AbstractITCase {
         ResourceTO ws1 = resourceService.read(RESOURCE_NAME_WS1);
         assertNotNull(ws1);
 
-        MappingTO ws1NewUMapping = ws1.getUmapping();
+        MappingTO ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // change purpose from NONE to BOTH
         for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
@@ -2232,15 +2126,14 @@ public class UserITCase extends AbstractITCase {
             }
         }
 
-        ws1.setUmapping(ws1NewUMapping);
-        ws1.setGmapping(ws1.getGmapping());
+        ws1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
 
         resourceService.update(RESOURCE_NAME_WS1, ws1);
         ResourceTO newWs1 = resourceService.read(ws1.getKey());
         assertNotNull(newWs1);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = newWs1.getUmapping().getItems();
+        Collection<MappingItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(7, mapItems.size());
 
@@ -2255,14 +2148,14 @@ public class UserITCase extends AbstractITCase {
         assertEquals(1, userTO.getPropagationStatusTOs().size());
         assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
 
-        final ConnObjectTO newUser = resourceService.getConnectorObject(RESOURCE_NAME_WS1, SubjectType.USER,
-                userTO.getKey());
+        ConnObjectTO newUser =
+                resourceService.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
 
         assertNotNull(newUser.getPlainAttrMap().get("NAME"));
         assertEquals("firstnameNew", newUser.getPlainAttrMap().get("NAME").getValues().get(0));
 
         // 4.  restore resource ws-target-resource-1 mapping
-        ws1NewUMapping = newWs1.getUmapping();
+        ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping();
         // restore purpose from BOTH to NONE
         for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
             if ("firstname".equals(itemTO.getIntAttrName())) {
@@ -2270,8 +2163,7 @@ public class UserITCase extends AbstractITCase {
             }
         }
 
-        newWs1.setUmapping(ws1NewUMapping);
-        newWs1.setGmapping(newWs1.getGmapping());
+        newWs1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
 
         resourceService.update(RESOURCE_NAME_WS1, newWs1);
     }
@@ -2350,7 +2242,7 @@ public class UserITCase extends AbstractITCase {
 
         // 4. Check that the LDAP resource has the correct password
         ConnObjectTO connObject =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, user.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
 
         assertNotNull(getLdapRemoteObject(
                 connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
@@ -2393,7 +2285,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
 
         // check if password has not changed
@@ -2414,7 +2306,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
 
         // check if password has been propagated and that saved userTO's password is null
@@ -2435,7 +2327,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
 
         // check if password has been correctly propagated on Syncope and resource-csv as usual
@@ -2480,8 +2372,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(12L);
-        membershipTO.getPlainAttrs().add(attrTO("postalAddress", "postalAddress"));
+        membershipTO.setRightKey(12L);
         userTO.getMemberships().add(membershipTO);
 
         userTO.getResources().add(RESOURCE_NAME_LDAP);
@@ -2491,22 +2382,19 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual.getDerAttrMap().get("csvuserid"));
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
         assertEquals("postalAddress", connObjectTO.getPlainAttrMap().get("postalAddress").getValues().get(0));
 
         UserMod userMod = new UserMod();
         userMod.setKey(actual.getKey());
 
-        MembershipMod membershipMod = new MembershipMod();
-        membershipMod.setGroup(12L);
-        membershipMod.getPlainAttrsToUpdate().add(attrMod("postalAddress", "newPostalAddress"));
-        userMod.getMembershipsToAdd().add(membershipMod);
+        userMod.getMembershipsToAdd().add(12L);
         userMod.getMembershipsToRemove().add(actual.getMemberships().iterator().next().getKey());
 
         actual = updateUser(userMod);
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
         assertNotNull(connObjectTO);
         assertEquals("newPostalAddress", connObjectTO.getPlainAttrMap().get("postalAddress").getValues().get(0));
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
index 14e2f9f..fdd25bd 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserSelfITCase.java
@@ -37,16 +37,14 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
 import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
@@ -93,7 +91,7 @@ public class UserSelfITCase extends AbstractITCase {
         // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
         UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
         MembershipTO membership = new MembershipTO();
-        membership.setGroupKey(3L);
+        membership.setRightKey(3L);
         userTO.getMemberships().add(membership);
         userTO.getResources().add(RESOURCE_NAME_TESTDB);
 
@@ -107,7 +105,7 @@ public class UserSelfITCase extends AbstractITCase {
         assertFalse(userTO.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -123,7 +121,7 @@ public class UserSelfITCase extends AbstractITCase {
         userTO = userWorkflowService.submitForm(form);
         assertNotNull(userTO);
         assertEquals("active", userTO.getStatus());
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey()));
     }
 
     @Test
@@ -171,16 +169,9 @@ public class UserSelfITCase extends AbstractITCase {
         assertFalse(created.getUsername().endsWith("XX"));
 
         // 2. self-update (username + memberships + resource) - works but needs approval
-        MembershipMod membershipMod = new MembershipMod();
-        membershipMod.setGroup(7L);
-        AttrMod testAttrMod = new AttrMod();
-        testAttrMod.setSchema("testAttribute");
-        testAttrMod.getValuesToBeAdded().add("a value");
-        membershipMod.getPlainAttrsToUpdate().add(testAttrMod);
-
         UserMod userMod = new UserMod();
         userMod.setUsername(created.getUsername() + "XX");
-        userMod.getMembershipsToAdd().add(membershipMod);
+        userMod.getMembershipsToAdd().add(7L);
         userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
         userMod.setPassword("newPassword123");
         StatusMod statusMod = new StatusMod();
@@ -199,7 +190,7 @@ public class UserSelfITCase extends AbstractITCase {
         // no propagation happened
         assertTrue(updated.getResources().isEmpty());
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, updated.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey());
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -220,7 +211,7 @@ public class UserSelfITCase extends AbstractITCase {
 
         // check that propagation also happened
         assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB));
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, updated.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), updated.getKey()));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
index 2432917..457f66d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserWorkflowITCase.java
@@ -56,14 +56,14 @@ public class UserWorkflowITCase extends AbstractITCase {
 
         // User with group 9 are defined in workflow as subject to approval
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(9L);
+        membershipTO.setRightKey(9L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user with group 9
         userTO = createUser(userTO);
         assertNotNull(userTO);
         assertEquals(1, userTO.getMemberships().size());
-        assertEquals(9, userTO.getMemberships().get(0).getGroupKey());
+        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
         assertEquals("createApproval", userTO.getStatus());
 
         // 2. request if there is any pending task for user just created
@@ -130,14 +130,14 @@ public class UserWorkflowITCase extends AbstractITCase {
 
         // User with group 9 are defined in workflow as subject to approval
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(9L);
+        membershipTO.setRightKey(9L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user with group 9 (and verify that no propagation occurred)
         userTO = createUser(userTO);
         assertNotNull(userTO);
         assertEquals(1, userTO.getMemberships().size());
-        assertEquals(9, userTO.getMemberships().get(0).getGroupKey());
+        assertEquals(9, userTO.getMemberships().get(0).getRightKey());
         assertEquals("createApproval", userTO.getStatus());
         assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
 
@@ -216,7 +216,7 @@ public class UserWorkflowITCase extends AbstractITCase {
 
         // User with group 9 are defined in workflow as subject to approval
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(9L);
+        membershipTO.setRightKey(9L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user with group 9 (and verify that no propagation occurred)

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
index 5001e5d..e161258 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirAttrITCase.java
@@ -26,9 +26,7 @@ import static org.junit.Assert.assertTrue;
 import java.util.Collections;
 import java.util.Map;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
@@ -39,13 +37,15 @@ import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -59,7 +59,7 @@ public class VirAttrITCase extends AbstractITCase {
         UserTO userTO = UserITCase.getUniqueSampleTO("issue16@apache.org");
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
+        membershipTO.setRightKey(8L);
         userTO.getMemberships().add(membershipTO);
 
         // 1. create user
@@ -101,7 +101,7 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
         // ----------------------------------
@@ -125,7 +125,7 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals("ws-target-resource-2", userTO.getPropagationStatusTOs().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
         // ----------------------------------
@@ -138,7 +138,7 @@ public class VirAttrITCase extends AbstractITCase {
         userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
         assertEquals("suspended", userTO.getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
         assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
@@ -148,7 +148,7 @@ public class VirAttrITCase extends AbstractITCase {
         userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
         assertEquals("active", userTO.getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
         assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
@@ -173,7 +173,7 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
         assertEquals("Surname2", connObjectTO.getPlainAttrMap().get("SURNAME").getValues().get(0));
 
@@ -196,7 +196,7 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
         assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
 
-        connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+        connObjectTO = resourceService.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey());
         assertNotNull(connObjectTO);
 
         // attribute "name" mapped on virtual attribute "virtualdata" should be reset
@@ -267,11 +267,11 @@ public class VirAttrITCase extends AbstractITCase {
     @Test
     public void issueSYNCOPE397() {
         ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
-        final MappingTO origMapping = SerializationUtils.clone(csv.getUmapping());
+        MappingTO origMapping = SerializationUtils.clone(csv.getProvisions().get(0).getMapping());
         try {
             // change mapping of resource-csv
             assertNotNull(origMapping);
-            for (MappingItemTO item : csv.getUmapping().getItems()) {
+            for (MappingItemTO item : csv.getProvisions().get(0).getMapping().getItems()) {
                 if ("email".equals(item.getIntAttrName())) {
                     // unset internal attribute mail and set virtual attribute virtualdata as mapped to external email
                     item.setIntMappingType(IntMappingType.UserVirtualSchema);
@@ -283,10 +283,10 @@ public class VirAttrITCase extends AbstractITCase {
 
             resourceService.update(csv.getKey(), csv);
             csv = resourceService.read(RESOURCE_NAME_CSV);
-            assertNotNull(csv.getUmapping());
+            assertNotNull(csv.getProvisions().get(0).getMapping());
 
             boolean found = false;
-            for (MappingItemTO item : csv.getUmapping().getItems()) {
+            for (MappingItemTO item : csv.getProvisions().get(0).getMapping().getItems()) {
                 if ("email".equals(item.getExtAttrName()) && "virtualdata".equals(item.getIntAttrName())) {
                     found = true;
                 }
@@ -335,7 +335,7 @@ public class VirAttrITCase extends AbstractITCase {
             assertEquals(2, toBeUpdated.getPropagationStatusTOs().size());
         } finally {
             // restore mapping of resource-csv
-            csv.setUmapping(origMapping);
+            csv.getProvisions().get(0).setMapping(origMapping);
             resourceService.update(csv.getKey(), csv);
         }
     }
@@ -447,12 +447,18 @@ public class VirAttrITCase extends AbstractITCase {
         // -------------------------------------------
         // Create a resource ad-hoc
         // -------------------------------------------
-        final ResourceTO resourceTO = new ResourceTO();
+        ResourceTO resourceTO = new ResourceTO();
 
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(107L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntAttrName("aLong");
@@ -460,7 +466,7 @@ public class VirAttrITCase extends AbstractITCase {
         item.setExtAttrName(groupName);
         item.setPurpose(MappingPurpose.PROPAGATION);
         item.setAccountid(true);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setExtAttrName("USERNAME");
@@ -476,7 +482,6 @@ public class VirAttrITCase extends AbstractITCase {
         item.setPurpose(MappingPurpose.PROPAGATION);
         mapping.getItems().add(item);
 
-        resourceTO.setUmapping(mapping);
         assertNotNull(getObject(
                 resourceService.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class));
         // -------------------------------------------
@@ -487,7 +492,6 @@ public class VirAttrITCase extends AbstractITCase {
         GroupTO groupTO = new GroupTO();
         groupTO.setName(groupName);
         groupTO.setRealm("/");
-        groupTO.getGVirAttrTemplates().add("rvirtualdata");
         groupTO.getVirAttrs().add(attrTO("rvirtualdata", "ml@group.it"));
         groupTO.getResources().add(RESOURCE_NAME_LDAP);
         groupTO = createGroup(groupTO);
@@ -507,8 +511,7 @@ public class VirAttrITCase extends AbstractITCase {
         userTO.getMemberships().clear();
 
         MembershipTO membership = new MembershipTO();
-        membership.setGroupKey(groupTO.getKey());
-        membership.getVirAttrs().add(attrTO("mvirtualdata", "mvirtualvalue"));
+        membership.setRightKey(groupTO.getKey());
         userTO.getMemberships().add(membership);
 
         userTO = createUser(userTO);
@@ -541,7 +544,7 @@ public class VirAttrITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getVirAttrs().clear();
 
-        final AttrTO virtualReadOnly = attrTO("virtualReadOnly", "");
+        AttrTO virtualReadOnly = attrTO("virtualReadOnly", "");
         virtualReadOnly.getValues().clear();
 
         userTO.getVirAttrs().add(virtualReadOnly);
@@ -563,174 +566,7 @@ public class VirAttrITCase extends AbstractITCase {
     }
 
     @Test
-    public void issueSYNCOPE458() {
-        // -------------------------------------------
-        // Create a group ad-hoc
-        // -------------------------------------------
-        final String groupName = "issueSYNCOPE458-Group-" + getUUIDString();
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/");
-        groupTO.getMVirAttrTemplates().add("mvirtualdata");
-        groupTO = createGroup(groupTO);
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Update resource-db-virattr mapping adding new membership virtual schema mapping
-        // -------------------------------------------
-        ResourceTO resourceDBVirAttr = resourceService.read(RESOURCE_NAME_DBVIRATTR);
-        assertNotNull(resourceDBVirAttr);
-
-        final MappingTO resourceUMapping = resourceDBVirAttr.getUmapping();
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntAttrName("mvirtualdata");
-        item.setIntMappingType(IntMappingType.MembershipVirtualSchema);
-        item.setExtAttrName("EMAIL");
-        item.setPurpose(MappingPurpose.BOTH);
-
-        resourceUMapping.addItem(item);
-
-        resourceDBVirAttr.setUmapping(resourceUMapping);
-
-        resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Create new user
-        // -------------------------------------------
-        UserTO userTO = UserITCase.getUniqueSampleTO("syncope458@syncope.apache.org");
-        userTO.getResources().clear();
-        userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
-        userTO.getVirAttrs().clear();
-        userTO.getDerAttrs().clear();
-        userTO.getMemberships().clear();
-
-        // add membership, with virtual attribute populated, to user
-        MembershipTO membership = new MembershipTO();
-        membership.setGroupKey(groupTO.getKey());
-        membership.getVirAttrs().add(attrTO("mvirtualdata", "syncope458@syncope.apache.org"));
-        userTO.getMemberships().add(membership);
-
-        // propagate user
-        userTO = createUser(userTO);
-        assertEquals(1, userTO.getPropagationStatusTOs().size());
-        assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
-       // -------------------------------------------
-
-        // 1. check if membership has virtual attribute populated
-        assertNotNull(userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata"));
-        assertEquals("syncope458@syncope.apache.org",
-                userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata").getValues().get(0));
-        // -------------------------------------------
-
-        // 2. update membership virtual attribute
-        MembershipMod membershipMod = new MembershipMod();
-        membershipMod.setGroup(groupTO.getKey());
-        membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope458_NEW@syncope.apache.org"));
-
-        UserMod userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToAdd().add(membershipMod);
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-        // 3. check again after update if membership has virtual attribute populated with new value
-        assertNotNull(userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata"));
-        assertEquals("syncope458_NEW@syncope.apache.org", userTO.getMemberships().get(0).getVirAttrMap().get(
-                "mvirtualdata").getValues().get(0));
-
-        // ----------------------------------------
-        // force cache expiring without any modification
-        // ----------------------------------------
-        String jdbcURL = null;
-        ConnInstanceTO connInstanceBean = connectorService.readByResource(RESOURCE_NAME_DBVIRATTR);
-        for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
-            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
-                jdbcURL = prop.getValues().iterator().next().toString();
-                prop.getValues().clear();
-                prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
-            }
-        }
-
-        connectorService.update(connInstanceBean.getKey(), connInstanceBean);
-
-        membershipMod = new MembershipMod();
-        membershipMod.setGroup(groupTO.getKey());
-        membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope458_updated@syncope.apache.org"));
-
-        userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToAdd().add(membershipMod);
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-        // ----------------------------------
-
-        // change attribute value directly on resource
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        String value = jdbcTemplate.queryForObject(
-                "SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
-        assertEquals("syncope458_NEW@syncope.apache.org", value);
-
-        jdbcTemplate.update("UPDATE testsync set EMAIL='syncope458_NEW_TWO@syncope.apache.org' WHERE ID=?", userTO.
-                getKey());
-
-        value = jdbcTemplate.queryForObject("SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
-        assertEquals("syncope458_NEW_TWO@syncope.apache.org", value);
-        // ----------------------------------------
-
-        // ----------------------------------------
-        // restore connector
-        // ----------------------------------------
-        for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
-            if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
-                prop.getValues().clear();
-                prop.getValues().add(jdbcURL);
-            }
-        }
-        connectorService.update(connInstanceBean.getKey(), connInstanceBean);
-        // ----------------------------------------
-
-        userTO = userService.read(userTO.getKey());
-        assertNotNull(userTO);
-        // 4. check virtual attribute synchronization after direct update on resource
-        assertEquals("syncope458_NEW_TWO@syncope.apache.org", userTO.getMemberships().get(0).getVirAttrMap().get(
-                "mvirtualdata").getValues().get(0));
-
-        // 5. remove membership virtual attribute
-        membershipMod = new MembershipMod();
-        membershipMod.setGroup(groupTO.getKey());
-        membershipMod.getVirAttrsToRemove().add("mvirtualdata");
-
-        userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToAdd().add(membershipMod);
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-        // check again after update if membership hasn't any virtual attribute
-        assertTrue(userTO.getMemberships().get(0).getVirAttrMap().isEmpty());
-
-        // -------------------------------------------
-        // Delete group ad-hoc and restore resource mapping
-        // -------------------------------------------
-        groupService.delete(groupTO.getKey());
-
-        resourceUMapping.removeItem(item);
-        resourceDBVirAttr.setUmapping(resourceUMapping);
-        resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
-        // -------------------------------------------
-    }
-
-    @Test
     public void issueSYNCOPE501() {
-        // PHASE 1: update only user virtual attributes
-
         // 1. create user and propagate him on resource-db-virattr
         UserTO userTO = UserITCase.getUniqueSampleTO("syncope501@apache.org");
         userTO.getResources().clear();
@@ -771,102 +607,5 @@ public class VirAttrITCase extends AbstractITCase {
         // 3. check that user virtual attribute has really been updated 
         assertFalse(userTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
         assertEquals("syncope501_updated@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
-
-        // ----------------------------------------------------------
-        // PHASE 2: update only membership virtual attributes
-        // -------------------------------------------
-        // Update resource-db-virattr mapping adding new membership virtual schema mapping
-        // -------------------------------------------
-        ResourceTO resourceDBVirAttr = resourceService.read(RESOURCE_NAME_DBVIRATTR);
-        assertNotNull(resourceDBVirAttr);
-
-        final MappingTO resourceUMapping = resourceDBVirAttr.getUmapping();
-
-        MappingItemTO item = new MappingItemTO();
-        item.setIntAttrName("mvirtualdata");
-        item.setIntMappingType(IntMappingType.MembershipVirtualSchema);
-        item.setExtAttrName("EMAIL");
-        item.setPurpose(MappingPurpose.BOTH);
-
-        resourceUMapping.addItem(item);
-
-        resourceDBVirAttr.setUmapping(resourceUMapping);
-
-        resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
-        // -------------------------------------------
-
-        // -------------------------------------------
-        // Create a group ad-hoc
-        // -------------------------------------------
-        final String groupName = "issueSYNCOPE501-Group-" + getUUIDString();
-        GroupTO groupTO = new GroupTO();
-        groupTO.setName(groupName);
-        groupTO.setRealm("/");
-        groupTO.getMVirAttrTemplates().add("mvirtualdata");
-        groupTO = createGroup(groupTO);
-        // -------------------------------------------
-
-        // 1. add membership, with virtual attribute populated, to user
-        MembershipMod membershipMod = new MembershipMod();
-        membershipMod.setGroup(groupTO.getKey());
-        membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope501membership@test.org"));
-
-        userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToAdd().add(membershipMod);
-        userMod.setPwdPropRequest(statusMod);
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-        assertEquals("syncope501membership@test.org",
-                userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata").getValues().get(0));
-
-        // 2. update only membership virtual attribute and propagate user
-        membershipMod = new MembershipMod();
-        membershipMod.setGroup(groupTO.getKey());
-        membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata",
-                "syncope501membership_updated@test.org"));
-        membershipMod.getVirAttrsToRemove().add("syncope501membership@test.org");
-
-        userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToAdd().add(membershipMod);
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
-        userMod.setPwdPropRequest(statusMod);
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-
-        // 3. check if change has been propagated
-        assertEquals("syncope501membership_updated@test.org", userTO.getMemberships().get(0).getVirAttrMap().
-                get("mvirtualdata").getValues().get(0));
-
-        // 4. delete membership and check on resource attribute deletion
-        userMod = new UserMod();
-        userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getKey());
-        userMod.setPwdPropRequest(statusMod);
-
-        userTO = updateUser(userMod);
-        assertNotNull(userTO);
-        assertTrue(userTO.getMemberships().isEmpty());
-
-        // read attribute value directly on resource
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
-
-        final String emailValue = jdbcTemplate.queryForObject(
-                "SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
-        assertTrue(StringUtils.isBlank(emailValue));
-        // ----------------------------------------
-
-        // -------------------------------------------
-        // Delete group ad-hoc and restore resource mapping
-        // -------------------------------------------
-        groupService.delete(groupTO.getKey());
-
-        resourceUMapping.removeItem(item);
-        resourceDBVirAttr.setUmapping(resourceUMapping);
-        resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
-        // -------------------------------------------
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
index c8259f0..a1ee34d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/VirSchemaITCase.java
@@ -28,7 +28,6 @@ import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -41,7 +40,7 @@ public class VirSchemaITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        List<VirSchemaTO> vSchemas = schemaService.list(AttributableType.USER, SchemaType.VIRTUAL);
+        List<VirSchemaTO> vSchemas = schemaService.list(SchemaType.VIRTUAL);
         assertFalse(vSchemas.isEmpty());
         for (VirSchemaTO vSchemaTO : vSchemas) {
             assertNotNull(vSchemaTO);
@@ -50,8 +49,7 @@ public class VirSchemaITCase extends AbstractITCase {
 
     @Test
     public void read() {
-        VirSchemaTO vSchemaTO = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL,
-                "mvirtualdata");
+        VirSchemaTO vSchemaTO = schemaService.read(SchemaType.VIRTUAL, "mvirtualdata");
         assertNotNull(vSchemaTO);
     }
 
@@ -60,22 +58,22 @@ public class VirSchemaITCase extends AbstractITCase {
         VirSchemaTO schema = new VirSchemaTO();
         schema.setKey("virtual");
 
-        VirSchemaTO actual = createSchema(AttributableType.USER, SchemaType.VIRTUAL, schema);
+        VirSchemaTO actual = createSchema(SchemaType.VIRTUAL, schema);
         assertNotNull(actual);
 
-        actual = schemaService.read(AttributableType.USER, SchemaType.VIRTUAL, actual.getKey());
+        actual = schemaService.read(SchemaType.VIRTUAL, actual.getKey());
         assertNotNull(actual);
     }
 
     @Test
     public void delete() {
-        VirSchemaTO schema = schemaService.read(AttributableType.GROUP, SchemaType.VIRTUAL, "rvirtualdata");
+        VirSchemaTO schema = schemaService.read(SchemaType.VIRTUAL, "rvirtualdata");
         assertNotNull(schema);
 
-        schemaService.delete(AttributableType.GROUP, SchemaType.VIRTUAL, schema.getKey());
+        schemaService.delete(SchemaType.VIRTUAL, schema.getKey());
 
         try {
-            schemaService.read(AttributableType.GROUP, SchemaType.VIRTUAL, "rvirtualdata");
+            schemaService.read(SchemaType.VIRTUAL, "rvirtualdata");
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
@@ -84,11 +82,11 @@ public class VirSchemaITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE323() {
-        VirSchemaTO actual = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, "mvirtualdata");
+        VirSchemaTO actual = schemaService.read(SchemaType.VIRTUAL, "mvirtualdata");
         assertNotNull(actual);
 
         try {
-            createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, actual);
+            createSchema(SchemaType.VIRTUAL, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
@@ -97,7 +95,7 @@ public class VirSchemaITCase extends AbstractITCase {
 
         actual.setKey(null);
         try {
-            createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, actual);
+            createSchema(SchemaType.VIRTUAL, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
@@ -111,7 +109,7 @@ public class VirSchemaITCase extends AbstractITCase {
         schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
 
         try {
-            createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, schema);
+            createSchema(SchemaType.VIRTUAL, schema);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidVirSchema, e.getType());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
index 106b1f1..9c9dd06 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/WorkflowITCase.java
@@ -26,13 +26,13 @@ import java.io.IOException;
 import java.io.InputStream;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.junit.Assume;
 import org.junit.Test;
 
 public class WorkflowITCase extends AbstractITCase {
 
-    private void exportDefinition(final SubjectType type) throws IOException {
+    private void exportDefinition(final AnyTypeKind type) throws IOException {
         Response response = workflowService.exportDefinition(type);
         assertTrue(response.getMediaType().toString().
                 startsWith(clientFactory.getContentType().getMediaType().toString()));
@@ -45,16 +45,16 @@ public class WorkflowITCase extends AbstractITCase {
     @Test
     public void exportUserDefinition() throws IOException {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-        exportDefinition(SubjectType.USER);
+        exportDefinition(AnyTypeKind.USER);
     }
 
     @Test
     public void getGroupDefinition() throws IOException {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
-        exportDefinition(SubjectType.GROUP);
+        exportDefinition(AnyTypeKind.GROUP);
     }
 
-    private void importDefinition(final SubjectType type) throws IOException {
+    private void importDefinition(final AnyTypeKind type) throws IOException {
         Response response = workflowService.exportDefinition(type);
         String definition = IOUtils.toString((InputStream) response.getEntity());
 
@@ -64,12 +64,12 @@ public class WorkflowITCase extends AbstractITCase {
     @Test
     public void updateUserDefinition() throws IOException {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
-        importDefinition(SubjectType.USER);
+        importDefinition(AnyTypeKind.USER);
     }
 
     @Test
     public void updateGroupDefinition() throws IOException {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForGroups(syncopeService));
-        importDefinition(SubjectType.GROUP);
+        importDefinition(AnyTypeKind.GROUP);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5253fd0..e1bdf65 100644
--- a/pom.xml
+++ b/pom.xml
@@ -378,7 +378,7 @@ under the License.
     <font-awesome.version>4.3.0</font-awesome.version>
     <ionicons.version>2.0.1</ionicons.version>
     <highlightjs.version>8.4-4</highlightjs.version>
-    <codemirror.version>5.1</codemirror.version>
+    <codemirror.version>5.3</codemirror.version>
     
     <wicket.version>7.0.0-M5</wicket.version>
     <wicket-jqueryui.version>7.0.0-M5</wicket-jqueryui.version>


[10/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/content.xml b/core/persistence-jpa/src/test/resources/content.xml
index df76835..fa63e84 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -22,8 +22,8 @@ under the License.
                creator="admin" lastModifier="admin"
                creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
 
-  <CPlainSchema name="password.cipher.algorithm" type="String"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
   <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
 
@@ -31,66 +31,66 @@ under the License.
   + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
   + provided as empty string: NotificationJob disabled
   + provided as non-empty string: NotificationJob runs according to the given value -->
-  <CPlainSchema name="notificationjob.cronExpression" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
   <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
   
-  <CPlainSchema name="notification.maxRetries" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
   <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
 
-  <CPlainSchema name="token.length" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
   <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
 
-  <CPlainSchema name="token.expireTime" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
   <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
 
-  <CPlainSchema name="selfRegistration.allowed" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
   <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
 
-  <CPlainSchema name="passwordReset.allowed" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
   <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
 
-  <CPlainSchema name="passwordReset.securityQuestion" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
   <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
 
-  <CPlainSchema name="authentication.statuses" type="String"
-                mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
   <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
   <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
 
   <!-- Save user login date upon successful authentication -->
-  <CPlainSchema name="log.lastlogindate" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
   <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
 
   <!-- For usage with admin console -->
-  <CPlainSchema name="admin.user.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.user.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="admin.group.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.group.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="admin.membership.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.membership.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
   
   <!-- sample policies -->
   <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
@@ -111,12 +111,25 @@ under the License.
           specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
   <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
           specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"groupAltSearchSchemas":[]}'/>
-    
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyType name="GROUP" kind="GROUP"/>
+  <AnyType name="OTHER" kind="ANY_OBJECT"/>
+      
   <Realm id="1" name="/" passwordPolicy_id="4"/>
   <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/>
   <Realm id="3" name="even" parent_id="1"/>
   <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
   
+  <AnyObject id="1" realm_id="1" type_name="OTHER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <AnyObject id="2" realm_id="1" type_name="OTHER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+
+  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2"/>
+  
   <SyncopeRole id="1" name="User reviewer"/>
   <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
   <SyncopeRole_entitlements entitlement="USER_LIST" role_id="1"/>
@@ -225,106 +238,92 @@ under the License.
                 creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
-  <Membership id="1" user_id="1" group_id="1"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="2" user_id="2" group_id="1"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="3" user_id="2" group_id="2"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="4" user_id="4" group_id="7"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="5" user_id="1" group_id="8"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="6" user_id="2" group_id="3"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <Membership id="7" user_id="5" group_id="14"
-              creator="admin" lastModifier="admin" 
-              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <UMembership id="1" user_id="1" group_id="1"/>
+  <UMembership id="2" user_id="2" group_id="1"/>
+  <UMembership id="3" user_id="2" group_id="2"/>
+  <UMembership id="4" user_id="4" group_id="7"/>
+  <UMembership id="5" user_id="1" group_id="8"/>
+  <UMembership id="6" user_id="2" group_id="3"/>
+  <UMembership id="7" user_id="5" group_id="14"/>
 
-  <UPlainSchema name="fullname" type="String"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
-  <UPlainSchema name="userId" type="String"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
-                validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <UPlainSchema name="loginDate" type="Date"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
-                conversionPattern="yyyy-MM-dd"/>
-  <UPlainSchema name="firstname" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="surname" type="String"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="type" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="email" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <UPlainSchema name="activationDate" type="Date"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <UPlainSchema name="uselessReadonly" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <UPlainSchema name="cool" type="Boolean"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="gender" type="Enum"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                enumerationValues="M;F"/>
-  <UPlainSchema name="aLong" type="Long"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="makeItDouble" type="Long"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <UPlainSchema name="obscure" type="Encrypted"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
-  <UPlainSchema name="photo" type="Binary"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                mimeType="image/jpeg"/>
+  <PlainSchema name="fullname" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
+  <PlainSchema name="userId" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="loginDate" type="Date"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd"/>
+  <PlainSchema name="firstname" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="surname" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="type" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="email" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="activationDate" type="Date"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="uselessReadonly" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
+  <PlainSchema name="cool" type="Boolean"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="gender" type="Enum"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               enumerationValues="M;F"/>
+  <PlainSchema name="aLong" type="Long"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="makeItDouble" type="Long"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="obscure" type="Encrypted"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
+  <PlainSchema name="photo" type="Binary"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               mimeType="image/jpeg"/>
 
-  <UDerSchema name="csvuserid" expression="firstname + ',' + surname"/>
-  <UDerSchema name="cn" expression="surname + ', ' + firstname"/>
-  <UDerSchema name="noschema" expression="surname + ', ' + notfound"/>
+  <DerSchema name="csvuserid" expression="firstname + ',' + surname"/>
+  <DerSchema name="cn" expression="surname + ', ' + firstname"/>
+  <DerSchema name="noschema" expression="surname + ', ' + notfound"/>
 
-  <UVirSchema name="virtualdata"/>
+  <VirSchema name="virtualdata"/>
 
-  <GPlainSchema name="icon" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
-  <GPlainSchema name="show" type="Boolean"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <GPlainSchema name="rderived_sx" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <GPlainSchema name="rderived_dx" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
-  <GPlainSchema name="title" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="icon" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
+  <PlainSchema name="show" type="Boolean"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_sx" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_dx" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
+  <PlainSchema name="title" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
 
-  <GDerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"/>
-  <GDerSchema name="displayProperty" expression="icon + ': ' + show"/>
-  <GDerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"/>
+  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"/>
+  <DerSchema name="displayProperty" expression="icon + ': ' + show"/>
+  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"/>
 
-  <GVirSchema name="rvirtualdata"/>
+  <VirSchema name="rvirtualdata"/>
 
   <!-- rderiveddata is used to verify der schema deletion -->
-  <GDerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/>
+  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/>
 
-  <MPlainSchema name="subscriptionDate" type="Date"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <MPlainSchema name="mderived_sx" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <MPlainSchema name="mderived_dx" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
-  <MPlainSchema name="postalAddress" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="subscriptionDate" type="Date"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="mderived_sx" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="mderived_dx" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
+  <PlainSchema name="postalAddress" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
 
-  <MDerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
-  <MDerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx"/>
+  <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
+  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx"/>
 
-  <MVirSchema name="mvirtualdata"/>
+  <VirSchema name="mvirtualdata"/>
   
   <UPlainAttr id="99" owner_id="1" schema_name="type"/>
   <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
@@ -389,93 +388,49 @@ under the License.
   <UPlainAttr id="126" owner_id="3" schema_name="type"/>
   <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
     
-  <UVirAttr id="1000" virSchema_name="virtualdata" owner_id="3"/>
+  <UVirAttr id="1000" schema_name="virtualdata" owner_id="3"/>
 
-  <UVirSchema name="virtualReadOnly" READONLY="1"/>
+  <VirSchema name="virtualReadOnly" READONLY="1"/>
   
-  <UDerAttr id="100" derSchema_name="cn" owner_id="3"/>
-  <UDerAttr id="101" derSchema_name="cn" owner_id="1"/>
+  <UDerAttr id="100" schema_name="cn" owner_id="3"/>
+  <UDerAttr id="101" schema_name="cn" owner_id="1"/>
 
-  <GPlainAttrTemplate id="600" owner_id="1" schema_name="icon"/>
-  <GPlainAttr id="600" owner_id="1" template_id="600"/>
+  <GPlainAttr id="600" owner_id="1" schema_name="icon"/>
   <GPlainAttrValue attribute_id="600" id="40" stringValue="niceIcon"/>
 
-  <GPlainAttrTemplate id="700" owner_id="2" schema_name="icon"/>
-  <GPlainAttr id="700" owner_id="2" template_id="700"/>
+  <GPlainAttr id="700" owner_id="2" schema_name="icon"/>
   <GPlainAttrValue attribute_id="700" id="41" stringValue="badIcon"/>
 
-  <GPlainAttrTemplate id="800" owner_id="1" schema_name="show"/>
-  <GPlainAttr id="800" owner_id="1" template_id="800"/>
+  <GPlainAttr id="800" owner_id="1"  schema_name="show"/>
   <GPlainAttrValue attribute_id="800" id="42" booleanValue="1"/>
 
-  <GPlainAttrTemplate id="900" owner_id="6" schema_name="icon"/>
-  <GPlainAttr id="900" owner_id="6" template_id="900"/>
+  <GPlainAttr id="900" owner_id="6" schema_name="icon"/>
   <GPlainAttrValue attribute_id="900" id="43" stringValue="icon6"/>
 
-  <GPlainAttrTemplate id="950" owner_id="4" schema_name="icon"/>
-  <GPlainAttr id="950" owner_id="4" template_id="950"/>
+  <GPlainAttr id="950" owner_id="4" schema_name="icon"/>
   <GPlainAttrValue attribute_id="950" id="44" stringValue="icon4"/>
 
-  <GPlainAttrTemplate id="992" owner_id="1" schema_name="rderived_sx"/>
-  <GPlainAttr id="992" owner_id="1" template_id="992"/>
+  <GPlainAttr id="992" owner_id="1" schema_name="rderived_sx"/>
   <GPlainAttrValue attribute_id="992" id="92" stringValue="sx"/>
 
-  <GPlainAttrTemplate id="993" owner_id="1" schema_name="rderived_dx"/>
-  <GPlainAttr id="993" owner_id="1" template_id="993"/>
+  <GPlainAttr id="993" owner_id="1" schema_name="rderived_dx"/>
   <GPlainAttrValue attribute_id="993" id="93" stringValue="dx"/>
 
-  <GPlainAttrTemplate id="994" owner_id="12" schema_name="title"/>
-  <GPlainAttr id="994" owner_id="12" template_id="994"/>
+  <GPlainAttr id="994" owner_id="12" schema_name="title"/>
   <GPlainAttrValue attribute_id="994" id="94" stringValue="r12"/>
   
-  <GPlainAttrTemplate id="995" owner_id="13" schema_name="title"/>
-  <GPlainAttr id="995" owner_id="13" template_id="995"/>
+  <GPlainAttr id="995" owner_id="13" schema_name="title"/>
   <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
 
-  <GDerAttrTemplate id="1000" owner_id="1" schema_name="rderiveddata"/>
-  <GDerAttr id="1000" owner_id="1" template_id="1000"/>
+  <GDerAttr id="1000" owner_id="1" schema_name="rderiveddata"/>
     
-  <GDerAttrTemplate id="1001" owner_id="1" schema_name="displayProperty"/>
-  <GDerAttr id="1001" owner_id="1" template_id="1001"/>
+  <GDerAttr id="1001" owner_id="1" schema_name="displayProperty"/>
   
-  <GDerAttrTemplate id="1002" owner_id="4" schema_name="displayProperty"/>
-  <GDerAttr id="1002" owner_id="4" template_id="1002"/>
-
-  <GDerAttrTemplate id="1003" owner_id="1" schema_name="rderToBePropagated"/>    
-  <GDerAttr id="1003" owner_id="1" template_id="1003"/>    
-
-  <GVirAttrTemplate id="98" owner_id="4" schema_name="rvirtualdata"/>
-  <GVirAttr id="98" owner_id="4" template_id="98"/>
-
-  <GVirAttrTemplate id="99" owner_id="3" schema_name="rvirtualdata"/>
-
-  <MPlainAttrTemplate id="98" owner_id="1" schema_name="mderived_sx"/>
-  
-  <MPlainAttrTemplate id="99" owner_id="1" schema_name="mderived_dx"/>
-
-  <MPlainAttrTemplate id="100" owner_id="7" schema_name="subscriptionDate"/>
-  <MPlainAttr id="100" owner_id="4" template_id="100"/>
-  <MPlainAttrValue attribute_id="100" id="90" dateValue="2009-05-26"/>
-  <MPlainAttrValue attribute_id="100" id="91" dateValue="2010-05-26 15:40:04"/>
-
-  <MPlainAttrTemplate id="101" owner_id="8" schema_name="subscriptionDate"/>
+  <GDerAttr id="1002" owner_id="4" schema_name="displayProperty"/>
 
-  <MPlainAttrTemplate id="102" owner_id="1" schema_name="mderived_sx"/>
-  <MPlainAttr id="102" owner_id="1" template_id="102"/>
-  <MPlainAttrValue attribute_id="102" id="92" stringValue="sx"/>
+  <GDerAttr id="1003" owner_id="1" schema_name="rderToBePropagated"/>    
 
-  <MPlainAttrTemplate id="103" owner_id="1" schema_name="mderived_dx"/>
-  <MPlainAttr id="103" owner_id="1" template_id="103"/>
-  <MPlainAttrValue attribute_id="103" id="93" stringValue="dx"/>
-
-  <MPlainAttrTemplate id="104" owner_id="12" schema_name="postalAddress"/>
-
-  <MDerAttrTemplate id="99" owner_id="1" schema_name="mderiveddata"/>
-  <MDerAttr id="99" owner_id="1" template_id="99"/>
-  
-  <MDerAttrTemplate id="100" owner_id="1" schema_name="mderToBePropagated"/>  
-    
-  <MVirAttrTemplate id="99" owner_id="2" schema_name="mvirtualdata"/>
+  <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
 
   <ConnInstance id="100" displayName="ConnInstance100"
                 location="${connid.location}"
@@ -632,7 +587,6 @@ under the License.
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="ws-target-resource-update-resetsynctoken" connector_id="100" enforceMandatoryCondition="1" propagationMode="TWO_PHASES"
                     randomPwdIfNotProvided="0" propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
-                    userializedSyncToken='{"value":null}'
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   <ExternalResource name="resource-ldap" connector_id="105"
@@ -641,7 +595,7 @@ under the License.
                     createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <ExternalResource_PropActions externalResource_name="resource-ldap"
+  <ExternalResource_PropActions resource_name="resource-ldap"
                                 actionClassName="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/>
   <ExternalResource name="ws-target-resource-nopropagation" connector_id="103"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="1" propagationMode="TWO_PHASES"
@@ -681,7 +635,7 @@ under the License.
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
-  <Policy_ExternalResource account_policy_id="5" resource_name="resource-testdb"/>
+  <Policy_ExternalResource accountPolicy_id="5" resource_name="resource-testdb"/>
     
   <SyncopeUser_ExternalResource user_id="1" resource_name="resource-testdb2"/>
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-delete"/>
@@ -695,264 +649,288 @@ under the License.
   <SyncopeGroup_ExternalResource group_id="10" resource_name="ws-target-resource-nopropagation3"/>
   <SyncopeGroup_ExternalResource group_id="12" resource_name="resource-csv"/>
   <SyncopeGroup_ExternalResource group_id="13" resource_name="resource-csv"/>
-
-  <UMapping id="15" resource_name="ws-target-resource-1"/>
-  <UMappingItem id="99" mapping_id="15" extAttrName="userId"
-                intMappingType="UserId" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="100" extAttrName="email" mapping_id="15"
-                intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="101" extAttrName="surname" mapping_id="15"
-                intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="102" mapping_id="15"
-                extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
-                accountid="0" password="1" purpose="PROPAGATION"/>
-  <UMappingItem id="335" mapping_id="15" 
-                extAttrName="fullname" intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="336" mapping_id="15"
-                extAttrName="type" intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="337" mapping_id="15"
-                extAttrName="name" intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="NONE"/>
+     
+  <Provision id="15" resource_name="ws-target-resource-1" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="15" provision_id="15"/>
+  <MappingItem id="99" mapping_id="15" extAttrName="userId"
+               intMappingType="UserId" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="100" extAttrName="email" mapping_id="15"
+               intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="101" extAttrName="surname" mapping_id="15"
+               intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="102" mapping_id="15"
+               extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
+               connObjectKey="0" password="1" purpose="PROPAGATION"/>
+  <MappingItem id="335" mapping_id="15" 
+               extAttrName="fullname" intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="336" mapping_id="15"
+               extAttrName="type" intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="337" mapping_id="15"
+               extAttrName="name" intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="NONE"/>
   
-  <UMapping id="12" resource_name="ws-target-resource-list-mappings-1"/>
-  <UMappingItem id="103" mapping_id="12"
-                extAttrName="email" intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="104" extAttrName="surname" mapping_id="12"
-                intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="PROPAGATION"/>
+  <Provision id="12" resource_name="ws-target-resource-list-mappings-1" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="12" provision_id="12"/>
+  <MappingItem id="103" mapping_id="12"
+               extAttrName="email" intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="104" extAttrName="surname" mapping_id="12"
+               intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
 
-  <UMapping id="13" resource_name="ws-target-resource-list-mappings-2"/>
-  <UMappingItem id="105" mapping_id="13"
-                extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="13" resource_name="ws-target-resource-list-mappings-2" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="13" provision_id="13"/>
+  <MappingItem id="105" mapping_id="13"
+               extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
 
-  <UMapping id="1" resource_name="ws-target-resource-2"/>
-  <UMappingItem id="106" mapping_id="1" extAttrName="fullname"
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="BOTH"/>
-  <UMappingItem id="107" mapping_id="1"
-                extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
-                accountid="0" password="1" purpose="BOTH"/>
-  <UMappingItem id="108" extAttrName="type" mapping_id="1"
-                intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="109" extAttrName="surname" mapping_id="1"
-                intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="type == 'F'"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="110" extAttrName="name" mapping_id="1"
-                intAttrName="virtualdata" intMappingType="UserVirtualSchema" mandatoryCondition="type == 'F'"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="111" extAttrName="fullname" mapping_id="1"
-                intAttrName="cn" intMappingType="UserDerivedSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="BOTH"/>
+  <Provision id="1" resource_name="ws-target-resource-2" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="1" provision_id="1"/>
+  <MappingItem id="106" mapping_id="1" extAttrName="fullname"
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="107" mapping_id="1"
+               extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
+               connObjectKey="0" password="1" purpose="BOTH"/>
+  <MappingItem id="108" extAttrName="type" mapping_id="1"
+               intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="109" extAttrName="surname" mapping_id="1"
+               intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="type == 'F'"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="110" extAttrName="name" mapping_id="1"
+               intAttrName="virtualdata" intMappingType="UserVirtualSchema" mandatoryCondition="type == 'F'"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="111" extAttrName="fullname" mapping_id="1"
+               intAttrName="cn" intMappingType="UserDerivedSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="BOTH"/>
     
-  <UMapping id="2" resource_name="ws-target-resource-update"/>
-  <UMappingItem id="112" extAttrName="email" mapping_id="2"
-                intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="113" extAttrName="userId" mapping_id="2"
-                intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="1" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="114" extAttrName="test3" mapping_id="2" 
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="PROPAGATION"/>
+  <Provision id="2" resource_name="ws-target-resource-update" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="2" provision_id="2"/>
+  <MappingItem id="112" extAttrName="email" mapping_id="2"
+               intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="113" extAttrName="userId" mapping_id="2"
+               intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="114" extAttrName="test3" mapping_id="2" 
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
     
-  <UMapping id="3" resource_name="ws-target-resource-nopropagation"/>
-  <UMappingItem id="115" mapping_id="3" extAttrName="fullname" 
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="3" resource_name="ws-target-resource-nopropagation" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="3" provision_id="3"/>
+  <MappingItem id="115" mapping_id="3" extAttrName="fullname" 
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
                      
-  <UMapping id="4" resource_name="ws-target-resource-nopropagation2"/>
-  <UMappingItem id="116" mapping_id="4" extAttrName="fullname" 
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="4" resource_name="ws-target-resource-nopropagation2" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="4" provision_id="4"/>
+  <MappingItem id="116" mapping_id="4" extAttrName="fullname" 
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
                      
-  <UMapping id="5" resource_name="ws-target-resource-nopropagation3"/>
-  <UMappingItem id="117" mapping_id="5" extAttrName="fullname"
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="5" resource_name="ws-target-resource-nopropagation3" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="5" provision_id="5"/>
+  <MappingItem id="117" mapping_id="5" extAttrName="fullname"
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
                      
-  <UMapping id="6" resource_name="ws-target-resource-nopropagation4"/>
-  <UMappingItem id="118" mapping_id="6"
-                extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="6" resource_name="ws-target-resource-nopropagation4" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="6" provision_id="6"/>
+  <MappingItem id="118" mapping_id="6"
+               extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
                        
-  <UMapping id="7" resource_name="resource-testdb"/>
-  <UMappingItem id="119" mapping_id="7"
-                extAttrName="id" intMappingType="Username" mandatoryCondition="true"
-                accountid="1" password="0" purpose="BOTH"/>
-  <UMappingItem id="120" mapping_id="7"
-                extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
-                accountid="0" password="1" purpose="BOTH"/>
+  <Provision id="7" resource_name="resource-testdb" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="7" provision_id="7"/>
+  <MappingItem id="119" mapping_id="7"
+               extAttrName="id" intMappingType="Username" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="120" mapping_id="7"
+               extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
+               connObjectKey="0" password="1" purpose="BOTH"/>
                      
-  <UMapping id="8" resource_name="resource-testdb2"/>
-  <UMappingItem id="121" mapping_id="8" extAttrName="id" 
-                intMappingType="Username" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
-  <UMappingItem id="122" mapping_id="8" extAttrName="__PASSWORD__" 
-                intMappingType="Password" mandatoryCondition="true"
-                accountid="0" password="1" purpose="PROPAGATION"/>
+  <Provision id="8" resource_name="resource-testdb2" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="8" provision_id="8"/>
+  <MappingItem id="121" mapping_id="8" extAttrName="id" 
+               intMappingType="Username" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
+  <MappingItem id="122" mapping_id="8" extAttrName="__PASSWORD__" 
+               intMappingType="Password" mandatoryCondition="true"
+               connObjectKey="0" password="1" purpose="PROPAGATION"/>
                          
-  <UMapping id="9" resource_name="resource-csv"/>
-  <UMappingItem id="200" extAttrName="id" mapping_id="9"
-                intMappingType="Username" mandatoryCondition="true"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="201" extAttrName="id" mapping_id="9"
-                intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="202" mapping_id="9"
-                extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
-                accountid="0" password="1" purpose="BOTH"/>
-  <UMappingItem id="203" extAttrName="name" mapping_id="9"
-                intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="204" extAttrName="surname" mapping_id="9"
-                intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="205" extAttrName="email" mapping_id="9"
-                intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="SYNCHRONIZATION"/>
-  <UMappingItem id="206" extAttrName="email" mapping_id="9"
-                intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
-                accountid="0" password="0" purpose="SYNCHRONIZATION"/>
-  <UMappingItem id="207" extAttrName="__NAME__" mapping_id="9"
-                intAttrName="csvuserid" intMappingType="UserDerivedSchema" mandatoryCondition="true"
-                accountid="1" password="0" purpose="BOTH"/>
-  <UMappingItem id="208" extAttrName="theirgroup" mapping_id="9"
-                intAttrName="rderToBePropagated" intMappingType="GroupDerivedSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="BOTH"/>
-  <UMappingItem id="209" extAttrName="membership" mapping_id="9"
-                intAttrName="mderToBePropagated" intMappingType="MembershipDerivedSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="BOTH"/>
+  <Provision id="9" resource_name="resource-csv" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="9" provision_id="9"/>
+  <MappingItem id="200" extAttrName="id" mapping_id="9"
+               intMappingType="Username" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="201" extAttrName="id" mapping_id="9"
+               intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="202" mapping_id="9"
+               extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
+               connObjectKey="0" password="1" purpose="BOTH"/>
+  <MappingItem id="203" extAttrName="name" mapping_id="9"
+               intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="204" extAttrName="surname" mapping_id="9"
+               intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="205" extAttrName="email" mapping_id="9"
+               intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="SYNCHRONIZATION"/>
+  <MappingItem id="206" extAttrName="email" mapping_id="9"
+               intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
+               connObjectKey="0" password="0" purpose="SYNCHRONIZATION"/>
+  <MappingItem id="207" extAttrName="__NAME__" mapping_id="9"
+               intAttrName="csvuserid" intMappingType="UserDerivedSchema" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="208" extAttrName="theirgroup" mapping_id="9"
+               intAttrName="rderToBePropagated" intMappingType="GroupDerivedSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  <MappingItem id="209" extAttrName="membership" mapping_id="9"
+               intAttrName="mderToBePropagated" intMappingType="AnyDerivedSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="BOTH"/>
                          
-  <UMapping id="10" resource_name="ws-target-resource-update-resetsynctoken"/>
-  <UMappingItem id="300" mapping_id="10"
-                extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="1" password="0" purpose="BOTH"/>
-  <UMappingItem id="301" mapping_id="10"
-                extAttrName="__PASSWORD__" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
-                accountid="0" password="1" purpose="BOTH"/>
+  <Provision id="10" resource_name="ws-target-resource-update-resetsynctoken" anyType_name="USER" objectClass="__ACCOUNT__"
+             serializedSyncToken='{"value":null}'/>
+  <Mapping id="10" provision_id="10"/>
+  <MappingItem id="300" mapping_id="10"
+               extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="301" mapping_id="10"
+               extAttrName="__PASSWORD__" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
+               connObjectKey="0" password="1" purpose="BOTH"/>
 
-  <UMapping id="11" resource_name="resource-ldap"
-            accountlink="&apos;uid=&apos; + username + &apos;,ou=people,o=isp&apos;"/>
-  <UMappingItem id="311" accountid="1" password="0" mapping_id="11"
-                extAttrName="cn" intAttrName="Username" intMappingType="Username"
-                mandatoryCondition="true" purpose="BOTH"/>
-  <UMappingItem id="312" accountid="0" password="1" mapping_id="11"
-                extAttrName="__PASSWORD__" intAttrName="Password" intMappingType="Password"
-                mandatoryCondition="true" purpose="BOTH"/>
-  <UMappingItem id="313" accountid="0" password="0" mapping_id="11"
-                extAttrName="sn" intAttrName="surname" intMappingType="UserPlainSchema"
-                mandatoryCondition="true" purpose="BOTH"/>
-  <UMappingItem id="314" accountid="0" password="0" mapping_id="11"
-                extAttrName="cn" intAttrName="fullname" intMappingType="UserPlainSchema"
-                mandatoryCondition="true" purpose="BOTH"/>
-  <UMappingItem id="315" accountid="0" password="0" mapping_id="11"
-                extAttrName="mail" intAttrName="email" intMappingType="UserPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="316" accountid="0" password="0" mapping_id="11"
-                extAttrName="title" intAttrName="title" intMappingType="GroupPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="317" accountid="0" password="0" mapping_id="11"
-                extAttrName="postalAddress" intAttrName="postalAddress" intMappingType="MembershipPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="318" accountid="0" password="0" mapping_id="11"
-                extAttrName="mail" intAttrName="userId" intMappingType="UserPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="319" accountid="0" password="0" mapping_id="11"
-                extAttrName="givenname" intAttrName="virtualReadOnly" intMappingType="UserVirtualSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="320" accountid="0" password="0" mapping_id="11"
-                extAttrName="registeredAddress" intAttrName="obscure" intMappingType="UserPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <UMappingItem id="321" accountid="0" password="0" mapping_id="11"
-                extAttrName="jpegPhoto" intAttrName="photo" intMappingType="UserPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  
-  <GMapping id="1" resource_name="resource-ldap"
-            accountlink="&apos;cn=&apos; + name + &apos;,ou=groups,o=isp&apos;"/>
-  <GMappingItem id="1" accountid="1" password="0" mapping_id="1"
-                extAttrName="cn" intAttrName="groupName" intMappingType="GroupName"
-                mandatoryCondition="true" purpose="BOTH"/>
-  <GMappingItem id="2" accountid="0" password="0" mapping_id="1"
-                extAttrName="owner" intAttrName="groupOwnerSchema" intMappingType="GroupOwnerSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <GMappingItem id="3" accountid="0" password="0" mapping_id="1"
-                extAttrName="description" intAttrName="title" intMappingType="GroupPlainSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
-  <GMappingItem id="4" extAttrName="businessCategory" mapping_id="1"
-                intAttrName="rvirtualdata" intMappingType="GroupVirtualSchema" mandatoryCondition="false"
-                accountid="0" password="0" purpose="BOTH"/>
+  <Provision id="11" resource_name="resource-ldap" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="11" provision_id="11"
+           connObjectLink="&apos;uid=&apos; + username + &apos;,ou=people,o=isp&apos;"/>
+  <MappingItem id="311" connObjectKey="1" password="0" mapping_id="11"
+               extAttrName="cn" intAttrName="Username" intMappingType="Username"
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="312" connObjectKey="0" password="1" mapping_id="11"
+               extAttrName="__PASSWORD__" intAttrName="Password" intMappingType="Password"
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="313" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="sn" intAttrName="surname" intMappingType="UserPlainSchema"
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="314" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="cn" intAttrName="fullname" intMappingType="UserPlainSchema"
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="315" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="mail" intAttrName="email" intMappingType="UserPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="316" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="title" intAttrName="title" intMappingType="GroupPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="317" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="postalAddress" intAttrName="postalAddress" intMappingType="AnyPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="318" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="mail" intAttrName="userId" intMappingType="UserPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="319" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="givenname" intAttrName="virtualReadOnly" intMappingType="UserVirtualSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="320" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="registeredAddress" intAttrName="obscure" intMappingType="UserPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="321" connObjectKey="0" password="0" mapping_id="11"
+               extAttrName="jpegPhoto" intAttrName="photo" intMappingType="UserPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
         
-  <UMapping id="16" resource_name="resource-db-sync"/>
-  <UMappingItem id="322" accountid="0" mapping_id="16"
-                extAttrName="EMAIL" intAttrName="email" intMappingType="UserPlainSchema" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <UMappingItem id="323" accountid="0" mapping_id="16"
-                extAttrName="SURNAME" intAttrName="fullname" intMappingType="UserPlainSchema" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <UMappingItem id="324" accountid="1" mapping_id="16"
-                extAttrName="ID" intAttrName="aLong" intMappingType="UserPlainSchema" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <UMappingItem id="325" accountid="0" mapping_id="16"
-                extAttrName="SURNAME" intAttrName="surname" intMappingType="UserPlainSchema" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <UMappingItem id="326" accountid="0" mapping_id="16"
-                extAttrName="USERNAME" intAttrName="Username" intMappingType="Username" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
-  <UMappingItem id="327" accountid="0" mapping_id="16"
-                extAttrName="EMAIL" intAttrName="userId" intMappingType="UserPlainSchema" 
-                mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <Provision id="20" resource_name="resource-ldap" anyType_name="GROUP" objectClass="__GROUP__"/>
+  <Mapping id="20" provision_id="20"
+           connObjectLink="&apos;cn=&apos; + name + &apos;,ou=groups,o=isp&apos;"/>
+  <MappingItem id="1" connObjectKey="1" password="0" mapping_id="20"
+               extAttrName="cn" intAttrName="groupName" intMappingType="GroupName"
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="2" connObjectKey="0" password="0" mapping_id="20"
+               extAttrName="owner" intAttrName="groupOwnerSchema" intMappingType="GroupOwnerSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="3" connObjectKey="0" password="0" mapping_id="20"
+               extAttrName="description" intAttrName="title" intMappingType="GroupPlainSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
+  <MappingItem id="4" extAttrName="businessCategory" mapping_id="20"
+               intAttrName="rvirtualdata" intMappingType="GroupVirtualSchema" mandatoryCondition="false"
+               connObjectKey="0" password="0" purpose="BOTH"/>
+  
+  <Provision id="16" resource_name="resource-db-sync" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="16" provision_id="16"/>
+  <MappingItem id="322" connObjectKey="0" mapping_id="16"
+               extAttrName="EMAIL" intAttrName="email" intMappingType="UserPlainSchema" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <MappingItem id="323" connObjectKey="0" mapping_id="16"
+               extAttrName="SURNAME" intAttrName="fullname" intMappingType="UserPlainSchema" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <MappingItem id="324" connObjectKey="1" mapping_id="16"
+               extAttrName="ID" intAttrName="aLong" intMappingType="UserPlainSchema" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <MappingItem id="325" connObjectKey="0" mapping_id="16"
+               extAttrName="SURNAME" intAttrName="surname" intMappingType="UserPlainSchema" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <MappingItem id="326" connObjectKey="0" mapping_id="16"
+               extAttrName="USERNAME" intAttrName="Username" intMappingType="Username" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
+  <MappingItem id="327" connObjectKey="0" mapping_id="16"
+               extAttrName="EMAIL" intAttrName="userId" intMappingType="UserPlainSchema" 
+               mandatoryCondition="false" password="0" purpose="BOTH"/>
               
-  <UMapping id="17" resource_name="resource-db-virattr"/>
-  <UMappingItem id="331" mapping_id="17" accountid="1" password="0"
-                extAttrName="id" intMappingType="UserId" 
-                mandatoryCondition="true" purpose="BOTH"/>
-  <UMappingItem id="332" mapping_id="17" accountid="0" password="0" 
-                extAttrName="USERNAME" intAttrName="virtualdata" intMappingType="UserVirtualSchema"
-                mandatoryCondition="false" purpose="BOTH"/>
+  <Provision id="17" resource_name="resource-db-virattr" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="17" provision_id="17"/>
+  <MappingItem id="331" mapping_id="17" connObjectKey="1" password="0"
+               extAttrName="id" intMappingType="UserId" 
+               mandatoryCondition="true" purpose="BOTH"/>
+  <MappingItem id="332" mapping_id="17" connObjectKey="0" password="0" 
+               extAttrName="USERNAME" intAttrName="virtualdata" intMappingType="UserVirtualSchema"
+               mandatoryCondition="false" purpose="BOTH"/>
                 
-  <UMapping id="18" resource_name="ws-target-resource-timeout"/>
-  <UMappingItem id="333" mapping_id="18" accountid="1" password="0"
-                extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema"
-                mandatoryCondition="true" purpose="PROPAGATION"/>
+  <Provision id="18" resource_name="ws-target-resource-timeout" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="18" provision_id="18"/>
+  <MappingItem id="333" mapping_id="18" connObjectKey="1" password="0"
+               extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema"
+               mandatoryCondition="true" purpose="PROPAGATION"/>
   
-  <UMapping id="19" resource_name="ws-target-resource-delete"/>
-  <UMappingItem id="334" mapping_id="19" extAttrName="userId" 
-                intMappingType="Username" mandatoryCondition="true"
-                accountid="1" password="0" purpose="PROPAGATION"/>
+  <Provision id="19" resource_name="ws-target-resource-delete" anyType_name="USER" objectClass="__ACCOUNT__"/>
+  <Mapping id="19" provision_id="19"/>
+  <MappingItem id="334" mapping_id="19" extAttrName="userId" 
+               intMappingType="Username" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="PROPAGATION"/>
   
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="1" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
-        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" subjectType="USER" subjectId="1"
+        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
   <TaskExec id="1" task_id="1" status="SUCCESS"/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="2" propagationMode="ONE_PHASE" propagationOperation="CREATE"
-        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" subjectType="USER" subjectId="1"
+        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="3" propagationMode="TWO_PHASES" propagationOperation="DELETE"
-        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" subjectType="USER" subjectId="1"
+        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-2" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"type","value":["type"]}]'/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="ASSIGN" matchingRule="UPDATE"
-        userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derAttrs":[{"schema":"cn","readonly":false,"values":[null]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"groupKey":8,"groupName":null,"plainAttrs":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derAttrs":[],"virAttrs":[]}]}'
-        groupTemplate='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": [],"gPlainAttrTemplates": [],"gDerAttrTemplates": [],"gVirAttrTemplates": [],"mPlainAttrTemplates": [],"mDerAttrTemplates": [],"mVirAttrTemplates": []}'/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="ASSIGN" matchingRule="UPDATE"/>
+  <AnyTemplate id="41" syncTask_id="4" anyType_name="USER"
+               template='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derAttrs":[{"schema":"cn","readonly":false,"values":[null]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"groupKey":8,"groupName":null,"plainAttrs":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derAttrs":[],"virAttrs":[]}]}'/>
+  <AnyTemplate id="42" syncTask_id="4" anyType_name="GROUP"
+               template='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": []}'/>
   <Task DTYPE="SchedTask" type="SCHEDULED" id="5" name="SampleJob Task" jobClassName="org.apache.syncope.core.provisioning.java.job.SampleJob" cronExpression="0 0 0 1 * ?"/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="6" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
-        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-nopropagation" subjectType="USER" subjectId="1"
+        objectClassName="__ACCOUNT__" resource_name="ws-target-resource-nopropagation" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
   <TaskExec id="6" task_id="6" status="SUCCESS"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="7" name="TestDB Task" resource_name="resource-testdb"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
-        userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["&apos;type a&apos;"]},{"schema":"userId","readonly":false,"values":["&apos;reconciled@syncope.apache.org&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;reconciled fullname&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;surname&apos;"]}],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"memberships":[]}'
-        groupTemplate='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": [],"gPlainAttrTemplates": [],"gDerAttrTemplates": [],"gVirAttrTemplates": [],"mPlainAttrTemplates": [],"mDerAttrTemplates": [],"mVirAttrTemplates": []}'/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
+  <AnyTemplate id="61" syncTask_id="7" anyType_name="USER"
+               template='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derAttrs":[{"schema":"cn","readonly":false,"values":[null]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"groupKey":8,"groupName":null,"plainAttrs":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derAttrs":[],"virAttrs":[]}]}'/>
+  <AnyTemplate id="62" syncTask_id="7" anyType_name="GROUP"
+               template='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": []}'/>
   <Task DTYPE="NotificationTask" type="NOTIFICATION" id="8" sender="admin@prova.org" subject="Notification for SYNCOPE-81" 
         textBody="NOTIFICATION-81" htmlBody="NOTIFICATION-81" traceLevel="ALL"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="9" name="TestDB2 Task" resource_name="resource-testdb2"
@@ -963,62 +941,88 @@ under the License.
         jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="11" name="LDAP Sync Task" resource_name="resource-ldap"
         destinationRealm_id="1" fullReconciliation="1" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
-        userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":false,"values":[""]}],"resources":["resource-ldap"],"propagationStatuses":[],"memberships":[]}'
-        groupTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"realm":null,"name":null,"userOwner":null,"groupOwner":null,"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"gPlainAttrTemplates":["show"],"gDerAttrTemplates":[],"gVirAttrTemplates":[],"mPlainAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
+  <AnyTemplate id="1" syncTask_id="11" anyType_name="USER"
+               template='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derAttrs":[{"schema":"cn","readonly":false,"values":[null]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"groupKey":8,"groupName":null,"plainAttrs":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derAttrs":[],"virAttrs":[]}]}'/>
+  <AnyTemplate id="2" syncTask_id="11" anyType_name="GROUP"
+               template='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": []}'/>
   <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="12" name="VirAttrCache test" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" fullReconciliation="1"
         jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
   <Task DTYPE="PushTask" type="PUSH" id="13" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="ASSIGN" matchingRule="IGNORE" 
-        userFilter="surname==Vivaldi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" 
+        unmatchingRule="ASSIGN" matchingRule="IGNORE"/>  
+  <AnyFilter id="131" anyType_name="USER" pushTask_id="13" filter="surname==Vivaldi"/>
+  <AnyFilter id="132" anyType_name="GROUP" pushTask_id="13" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="14" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="PROVISION" matchingRule="IGNORE" 
-        userFilter="surname==Bellini" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" 
+        unmatchingRule="PROVISION" matchingRule="IGNORE"/>
+  <AnyFilter id="141" anyType_name="USER" pushTask_id="14" filter="surname==Bellini"/>
+  <AnyFilter id="142" anyType_name="GROUP" pushTask_id="14" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="15" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="UNLINK" matchingRule="IGNORE" 
-        userFilter="surname==Puccini" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="UNLINK" matchingRule="IGNORE"/>
+  <AnyFilter id="151" anyType_name="USER" pushTask_id="15" filter="surname==Puccini"/>
+  <AnyFilter id="152" anyType_name="GROUP" pushTask_id="15" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="16" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="IGNORE" 
-        userFilter="surname==Verdi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" 
+        unmatchingRule="IGNORE" matchingRule="IGNORE"/>
+  <AnyFilter id="161" anyType_name="USER" pushTask_id="16" filter="surname==Verdi"/>
+  <AnyFilter id="162" anyType_name="GROUP" pushTask_id="16" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="17" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="ASSIGN" matchingRule="UPDATE" 
-        userFilter="username==_NO_ONE_" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="ASSIGN" matchingRule="UPDATE"/>
+  <AnyFilter id="171" anyType_name="USER" pushTask_id="17" filter="username==_NO_ONE_"/>
+  <AnyFilter id="172" anyType_name="GROUP" pushTask_id="17" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="18" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="DEPROVISION" 
-        userFilter="surname==Verdi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="IGNORE" matchingRule="DEPROVISION"/>
+  <AnyFilter id="181" anyType_name="USER" pushTask_id="18" filter="surname==Verdi"/>
+  <AnyFilter id="182" anyType_name="GROUP" pushTask_id="18" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="19" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="UNASSIGN" 
-        userFilter="surname==Rossini" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="IGNORE" matchingRule="UNASSIGN"/>
+  <AnyFilter id="191" anyType_name="USER" pushTask_id="19" filter="surname==Rossini"/>
+  <AnyFilter id="192" anyType_name="GROUP" pushTask_id="19" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="20" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="LINK" 
-        userFilter="surname==Verdi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="IGNORE" matchingRule="LINK"/>
+  <AnyFilter id="201" anyType_name="USER" pushTask_id="20" filter="surname==Verdi"/>
+  <AnyFilter id="202" anyType_name="GROUP" pushTask_id="20" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="21" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="UNLINK" 
-        userFilter="surname==Verdi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="IGNORE" matchingRule="UNLINK"/>
+  <AnyFilter id="211" anyType_name="USER" pushTask_id="21" filter="surname==Verdi"/>
+  <AnyFilter id="212" anyType_name="GROUP" pushTask_id="21" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="22" name="Export on resource-testdb2" resource_name="resource-testdb2"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="IGNORE" matchingRule="UPDATE" 
-        userFilter="surname==Verdi" groupFilter="name==_NO_ONE_"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="IGNORE" matchingRule="UPDATE"/>
+  <AnyFilter id="221" anyType_name="USER" pushTask_id="22" filter="surname==Verdi"/>
+  <AnyFilter id="222" anyType_name="GROUP" pushTask_id="22" filter="name==_NO_ONE_"/>
   <Task DTYPE="PushTask" type="PUSH" id="23" name="Export on resource-ldap" resource_name="resource-ldap"
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob" unmatchingRule="ASSIGN" matchingRule="UNLINK" 
-        userFilter="username==_NO_ONE_" groupFilter="name==citizen"/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.PushJob"
+        unmatchingRule="ASSIGN" matchingRule="UNLINK"/>
+  <AnyFilter id="231" anyType_name="USER" pushTask_id="23" filter="username==_NO_ONE_"/>
+  <AnyFilter id="232" anyType_name="GROUP" pushTask_id="23" filter="name==citizen"/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="24" name="CSV Task (update matching; provision unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
-        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"
-        userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"firstname","readonly":false,"values":[""]},{"schema":"userId","readonly":false,"values":["&apos;test&apos;"]},{"schema":"fullname","readonly":false,"values":["&apos;test&apos;"]},{"schema":"surname","readonly":false,"values":["&apos;test&apos;"]}],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[]}'
-        groupTemplate='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": [],"gPlainAttrTemplates": [],"gDerAttrTemplates": [],"gVirAttrTemplates": [],"mPlainAttrTemplates": [],"mDerAttrTemplates": [],"mVirAttrTemplates": []}'/>
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
+  <AnyTemplate id="3" syncTask_id="24" anyType_name="USER"
+               template='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}],"derAttrs":[{"schema":"cn","readonly":false,"values":[null]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"groupKey":8,"groupName":null,"plainAttrs":[{"schema":"subscriptionDate","readonly":false,"values":["&apos;2009-08-18T16:33:12.203+0200&apos;"]}],"derAttrs":[],"virAttrs":[]}]}'/>
+  <AnyTemplate id="4" syncTask_id="24" anyType_name="GROUP"
+               template='{"creator": null,"creationDate": null,"lastModifier": null,"lastChangeDate": null,"key": 0,"name": null,"userOwner": null,"groupOwner": null,"plainAttrs": [], "derAttrs": [],"virAttrs": [],"resources": [],"propagationStatuses": []}'/>
   <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="25" name="CSV (unlink matching; ignore unmatching)" resource_name="resource-csv"
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="IGNORE" matchingRule="UNLINK"/>
@@ -1026,12 +1030,13 @@ under the License.
         destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="ASSIGN" matchingRule="IGNORE"/>
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" propagationMode="ONE_PHASE" propagationOperation="CREATE"
-        objectClassName="__ACCOUNT__" resource_name="resource-testdb" subjectType="USER" subjectId="1"
+        objectClassName="__ACCOUNT__" resource_name="resource-testdb" anyTypeKind="USER" anyKey="1"
         xmlAttributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/>
 
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
                 sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
                 traceLevel="FAILURES" userAbout="token!=$null"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
   <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
   
   <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
@@ -1041,9 +1046,9 @@ under the License.
 
   <Notification id="10" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" 
                 traceLevel="FAILURES"
-                userAbout="fullname==*o*;fullname==*i*"
                 recipients="$groups==7"
                 recipientAttrType="UserPlainSchema" recipientAttrName="email" active="1"/>
+  <AnyAbout id="10" anyType_name="USER" notification_id="10" about="fullname==*o*;fullname==*i*"/>
   <Notification_events Notification_id="10" event="[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]"/>
   <Notification_events Notification_id="10" event="[CUSTOM]:[]:[]:[unexisting2]:[SUCCESS]"/>
     

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
new file mode 100644
index 0000000..6b423d5
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+
+public interface AnyObjectProvisioningManager extends ProvisioningManager<AnyObjectTO, AnyObjectMod> {
+
+    Pair<Long, List<PropagationStatus>> create(AnyObjectTO anyObjectTO, Set<String> excludedResources);
+
+    Pair<Long, List<PropagationStatus>> update(AnyObjectMod anyObjectMod, Set<String> excludedResources);
+
+}


[04/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
index fe1a8aa..992507b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
@@ -18,9 +18,9 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -53,7 +53,7 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+    public <T extends AnyTO> SyncDelta beforeProvision(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
             final T subject) throws JobExecutionException {
@@ -68,7 +68,7 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
             final T subject,
@@ -101,7 +101,7 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> void after(
+    public <T extends AnyTO> void after(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
             final T subject,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
index 7acc2ae..b13213a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
@@ -22,21 +22,22 @@ import java.util.Collections;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 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.group.GMapping;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.job.PushJob;
 import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
@@ -65,7 +66,7 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
      * Search DAO.
      */
     @Autowired
-    private SubjectSearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     /**
      * Group DAO.
@@ -73,28 +74,49 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
     @Autowired
     private GroupDAO groupDAO;
 
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+        AnyDAO<?> result;
+        switch (anyTypeKind) {
+            case USER:
+                result = userDAO;
+                break;
+
+            case GROUP:
+                result = groupDAO;
+                break;
+
+            case ANY_OBJECT:
+            default:
+                result = anyObjectDAO;
+        }
+
+        return result;
+    }
+
     @Override
     protected String executeWithSecurityContext(
             final PushTask pushTask,
             final Connector connector,
-            final UMapping uMapping,
-            final GMapping rMapping,
             final boolean dryRun) throws JobExecutionException {
-        LOG.debug("Execute synchronization (push) with resource {}", pushTask.getResource());
 
-        final ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+        LOG.debug("Executing push on {}", pushTask.getResource());
+
+        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
         if (actions != null) {
             profile.getActions().addAll(actions);
         }
         profile.setDryRun(dryRun);
         profile.setResAct(null);
 
-        final UserPushResultHandler uhandler =
+        UserPushResultHandler uhandler =
                 (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
         uhandler.setProfile(profile);
 
-        final GroupPushResultHandler rhandler =
+        GroupPushResultHandler rhandler =
                 (GroupPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
         rhandler.setProfile(profile);
@@ -105,43 +127,28 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
             }
         }
 
-        if (uMapping != null) {
-            final int count = userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-            for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
-                final List<User> localUsers = StringUtils.isBlank(pushTask.getUserFilter())
-                        ? userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
-                        : searchDAO.<User>search(SyncopeConstants.FULL_ADMIN_REALMS,
-                                SearchCondConverter.convert(pushTask.getUserFilter()),
-                                Collections.<OrderByClause>emptyList(), SubjectType.USER);
-
-                for (User localUser : localUsers) {
-                    try {
-                        // user propagation
-                        uhandler.handle(localUser.getKey());
-                    } catch (Exception e) {
-                        LOG.warn("Failure pushing user '{}' on '{}'", localUser, pushTask.getResource(), e);
-                        throw new JobExecutionException("While pushing users on connector", e);
-                    }
-                }
-            }
-        }
-
-        if (rMapping != null) {
-            final int count = groupDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-            for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
-                final List<Group> localGroups = StringUtils.isBlank(pushTask.getGroupFilter())
-                        ? groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
-                        : searchDAO.<Group>search(SyncopeConstants.FULL_ADMIN_REALMS,
-                                SearchCondConverter.convert(pushTask.getGroupFilter()),
-                                Collections.<OrderByClause>emptyList(), SubjectType.GROUP);
-
-                for (Group localGroup : localGroups) {
-                    try {
-                        // group propagation
-                        rhandler.handle(localGroup.getKey());
-                    } catch (Exception e) {
-                        LOG.warn("Failure pushing group '{}' on '{}'", localGroup, pushTask.getResource(), e);
-                        throw new JobExecutionException("While pushing groups on connector", e);
+        for (Provision provision : pushTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
+                String filter = pushTask.getFilter(provision.getAnyType()) == null
+                        ? null
+                        : pushTask.getFilter(provision.getAnyType()).get();
+
+                int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+                for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+                    List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter)
+                            ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
+                            : searchDAO.<User>search(SyncopeConstants.FULL_ADMIN_REALMS,
+                                    SearchCondConverter.convert(filter),
+                                    Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
+
+                    for (Any<?, ?, ?> any : localAnys) {
+                        try {
+                            uhandler.handle(any.getKey());
+                        } catch (Exception e) {
+                            LOG.warn("Failure pushing user '{}' on '{}'", any, pushTask.getResource(), e);
+                            throw new JobExecutionException("While pushing users on connector", e);
+                        }
                     }
                 }
             }
@@ -153,10 +160,8 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
             }
         }
 
-        final String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
-
+        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
         LOG.debug("Sync result: {}", result);
-
         return result;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
index 54e5115..1e19d02 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
@@ -23,20 +23,21 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.mod.ReferenceMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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.provisioning.api.job.SyncJob;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
 import org.identityconnectors.framework.common.objects.SyncToken;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -57,7 +58,7 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
     private GroupWorkflowAdapter gwfAdapter;
 
     @Autowired
-    protected SyncUtils syncUtilities;
+    protected SyncUtils syncUtils;
 
     protected void setGroupOwners(final GroupSyncResultHandler rhandler) {
         for (Map.Entry<Long, String> entry : rhandler.getGroupOwnerMap().entrySet()) {
@@ -68,24 +69,24 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                 groupMod.setGroupOwner(null);
                 groupMod.setUserOwner(null);
             } else {
-                Long userId = syncUtilities.findMatchingAttributableKey(
-                        ObjectClass.ACCOUNT,
+                Long userKey = syncUtils.findMatchingAnyKey(
+                        anyTypeDAO.findUser(),
                         entry.getValue(),
                         rhandler.getProfile().getTask().getResource(),
                         rhandler.getProfile().getConnector());
 
-                if (userId == null) {
-                    Long groupId = syncUtilities.findMatchingAttributableKey(
-                            ObjectClass.GROUP,
+                if (userKey == null) {
+                    Long groupKey = syncUtils.findMatchingAnyKey(
+                            anyTypeDAO.findGroup(),
                             entry.getValue(),
                             rhandler.getProfile().getTask().getResource(),
                             rhandler.getProfile().getConnector());
 
-                    if (groupId != null) {
-                        groupMod.setGroupOwner(new ReferenceMod(groupId));
+                    if (groupKey != null) {
+                        groupMod.setGroupOwner(new ReferenceMod(groupKey));
                     }
                 } else {
-                    groupMod.setUserOwner(new ReferenceMod(userId));
+                    groupMod.setUserOwner(new ReferenceMod(userKey));
                 }
             }
 
@@ -97,11 +98,9 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
     protected String executeWithSecurityContext(
             final SyncTask syncTask,
             final Connector connector,
-            final UMapping uMapping,
-            final GMapping rMapping,
             final boolean dryRun) throws JobExecutionException {
 
-        LOG.debug("Execute synchronization with token {}", syncTask.getResource().getUsyncToken());
+        LOG.debug("Executing sync on {}", syncTask.getResource());
 
         ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
         if (actions != null) {
@@ -110,6 +109,12 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
         profile.setDryRun(dryRun);
         profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
 
+        // Prepare handler for SyncDelta objects (any objects)
+        AnyObjectSyncResultHandler ahandler =
+                (AnyObjectSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
         // Prepare handler for SyncDelta objects (users)
         UserSyncResultHandler uhandler =
                 (UserSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
@@ -117,10 +122,10 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
         uhandler.setProfile(profile);
 
         // Prepare handler for SyncDelta objects (groups)
-        GroupSyncResultHandler rhandler =
+        GroupSyncResultHandler ghandler =
                 (GroupSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        rhandler.setProfile(profile);
+        ghandler.setProfile(profile);
 
         if (actions != null && !profile.isDryRun()) {
             for (SyncActions action : actions) {
@@ -129,47 +134,49 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
         }
 
         try {
-            SyncToken latestUSyncToken = null;
-            if (uMapping != null && !syncTask.isFullReconciliation()) {
-                latestUSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
-            }
-            SyncToken latestRSyncToken = null;
-            if (rMapping != null && !syncTask.isFullReconciliation()) {
-                latestRSyncToken = connector.getLatestSyncToken(ObjectClass.GROUP);
-            }
-
-            if (syncTask.isFullReconciliation()) {
-                if (uMapping != null) {
-                    connector.getAllObjects(ObjectClass.ACCOUNT, uhandler,
-                            connector.getOperationOptions(uMapping.getItems()));
-                }
-                if (rMapping != null) {
-                    connector.getAllObjects(ObjectClass.GROUP, rhandler,
-                            connector.getOperationOptions(rMapping.getItems()));
-                }
-            } else {
-                if (uMapping != null) {
-                    connector.sync(ObjectClass.ACCOUNT, syncTask.getResource().getUsyncToken(), uhandler,
-                            connector.getOperationOptions(uMapping.getItems()));
+            for (Provision provision : syncTask.getResource().getProvisions()) {
+                SyncResultsHandler handler;
+                switch (provision.getAnyType().getKind()) {
+                    case USER:
+                        handler = uhandler;
+                        break;
+
+                    case GROUP:
+                        handler = ghandler;
+                        break;
+
+                    case ANY_OBJECT:
+                    default:
+                        handler = ahandler;
                 }
-                if (rMapping != null) {
-                    connector.sync(ObjectClass.GROUP, syncTask.getResource().getRsyncToken(), rhandler,
-                            connector.getOperationOptions(rMapping.getItems()));
+
+                SyncToken latestSyncToken = null;
+                if (provision.getMapping() != null && !syncTask.isFullReconciliation()) {
+                    latestSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
                 }
-            }
 
-            if (!dryRun && !syncTask.isFullReconciliation()) {
-                try {
-                    ExternalResource resource = resourceDAO.find(syncTask.getResource().getKey());
-                    if (uMapping != null) {
-                        resource.setUsyncToken(latestUSyncToken);
+                if (syncTask.isFullReconciliation()) {
+                    if (provision.getMapping() != null) {
+                        connector.getAllObjects(provision.getObjectClass(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
+                    }
+                } else {
+                    if (provision.getMapping() != null) {
+                        connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
                     }
-                    if (rMapping != null) {
-                        resource.setRsyncToken(latestRSyncToken);
+                }
+
+                if (!dryRun && !syncTask.isFullReconciliation()) {
+                    try {
+                        ExternalResource resource = resourceDAO.find(syncTask.getResource().getKey());
+                        if (provision.getMapping() != null) {
+                            provision.setSyncToken(latestSyncToken);
+                        }
+                        resourceDAO.save(resource);
+                    } catch (Exception e) {
+                        throw new JobExecutionException("While updating SyncToken", e);
                     }
-                    resourceDAO.save(resource);
-                } catch (Exception e) {
-                    throw new JobExecutionException("While updating SyncToken", e);
                 }
             }
         } catch (Throwable t) {
@@ -177,7 +184,7 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
         }
 
         try {
-            setGroupOwners(rhandler);
+            setGroupOwners(ghandler);
         } catch (Exception e) {
             LOG.error("While setting group owners", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index 7dabe8f..e751522 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -25,29 +25,32 @@ import java.util.List;
 import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+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.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.Connector;
@@ -56,7 +59,6 @@ import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.OperationalAttributes;
 import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
 import org.slf4j.Logger;
@@ -84,6 +86,15 @@ public class SyncUtils {
     @Autowired
     protected PlainSchemaDAO plainSchemaDAO;
 
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    /**
+     * Any Object DAO.
+     */
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
     /**
      * User DAO.
      */
@@ -100,43 +111,49 @@ public class SyncUtils {
      * Search DAO.
      */
     @Autowired
-    protected SubjectSearchDAO searchDAO;
+    protected AnySearchDAO searchDAO;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
-    public Long findMatchingAttributableKey(
-            final ObjectClass oclass,
+    public Long findMatchingAnyKey(
+            final AnyType anyType,
             final String name,
             final ExternalResource resource,
             final Connector connector) {
 
+        Provision provision = resource.getProvision(anyType);
+        if (provision == null) {
+            return null;
+        }
+
         Long result = null;
 
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(oclass);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind());
 
-        final List<ConnectorObject> found = connector.search(oclass,
+        List<ConnectorObject> found = connector.search(provision.getObjectClass(),
                 new EqualsFilter(new Name(name)), connector.getOperationOptions(
-                        attrUtils.getMappingItems(resource, MappingPurpose.SYNCHRONIZATION)));
+                        anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)));
 
         if (found.isEmpty()) {
-            LOG.debug("No {} found on {} with __NAME__ {}", oclass, resource, name);
+            LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
         } else {
             if (found.size() > 1) {
-                LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only", oclass, resource, name);
+                LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
+                        provision.getObjectClass(), resource, name);
             }
 
             ConnectorObject connObj = found.iterator().next();
             try {
-                List<Long> subjectKeys = findExisting(connObj.getUid().getUidValue(), connObj, resource, attrUtils);
-                if (subjectKeys.isEmpty()) {
-                    LOG.debug("No matching {} found for {}, aborting", attrUtils.getType(), connObj);
+                List<Long> anyKeys = findExisting(connObj.getUid().getUidValue(), connObj, provision, anyUtils);
+                if (anyKeys.isEmpty()) {
+                    LOG.debug("No matching {} found for {}, aborting", anyUtils.getAnyTypeKind(), connObj);
                 } else {
-                    if (subjectKeys.size() > 1) {
-                        LOG.warn("More than one {} found {} - taking first only", attrUtils.getType(), subjectKeys);
+                    if (anyKeys.size() > 1) {
+                        LOG.warn("More than one {} found {} - taking first only", anyUtils.getAnyTypeKind(), anyKeys);
                     }
 
-                    result = subjectKeys.iterator().next();
+                    result = anyKeys.iterator().next();
                 }
             } catch (IllegalArgumentException e) {
                 LOG.warn(e.getMessage());
@@ -146,21 +163,26 @@ public class SyncUtils {
         return result;
     }
 
-    private SubjectDAO<?, ?, ?> getSubjectDAO(final MappingItem accountIdItem) {
-        return AttributableType.USER == accountIdItem.getIntMappingType().getAttributableType() ? userDAO : groupDAO;
+    private AnyDAO<?> getAnyDAO(final MappingItem accountIdItem) {
+        return AnyTypeKind.USER == accountIdItem.getIntMappingType().getAnyTypeKind()
+                ? userDAO
+                : AnyTypeKind.ANY_OBJECT == accountIdItem.getIntMappingType().getAnyTypeKind()
+                        ? anyObjectDAO
+                        : groupDAO;
     }
 
-    private List<Long> findByAccountIdItem(
-            final String uid, final ExternalResource resource, final AttributableUtils attrUtils) {
-        final List<Long> result = new ArrayList<>();
+    private List<Long> findByConnObjectKeyItem(
+            final String uid, final Provision provision, final AnyUtils anyUtils) {
 
-        final MappingItem accountIdItem = attrUtils.getAccountIdItem(resource);
-        switch (accountIdItem.getIntMappingType()) {
+        List<Long> result = new ArrayList<>();
+
+        MappingItem connObjectKeyItem = anyUtils.getConnObjectKeyItem(provision);
+        switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-                final PlainAttrValue value = attrUtils.newPlainAttrValue();
+                final PlainAttrValue value = anyUtils.newPlainAttrValue();
 
-                PlainSchema schema = plainSchemaDAO.find(accountIdItem.getIntAttrName(), attrUtils.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
                 if (schema == null) {
                     value.setStringValue(uid);
                 } else {
@@ -172,19 +194,18 @@ public class SyncUtils {
                     }
                 }
 
-                List<? extends Subject<?, ?, ?>> subjects =
-                        getSubjectDAO(accountIdItem).findByAttrValue(accountIdItem.getIntAttrName(), value, attrUtils);
-                for (Subject<?, ?, ?> subject : subjects) {
-                    result.add(subject.getKey());
+                List<? extends Any<?, ?, ?>> anys =
+                        getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value);
+                for (Any<?, ?, ?> any : anys) {
+                    result.add(any.getKey());
                 }
                 break;
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-                subjects = getSubjectDAO(accountIdItem).
-                        findByDerAttrValue(accountIdItem.getIntAttrName(), uid, attrUtils);
-                for (Subject<?, ?, ?> subject : subjects) {
-                    result.add(subject.getKey());
+                anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), uid);
+                for (Any<?, ?, ?> any : anys) {
+                    result.add(any.getKey());
                 }
                 break;
 
@@ -217,40 +238,40 @@ public class SyncUtils {
                 break;
 
             default:
-                LOG.error("Invalid accountId type '{}'", accountIdItem.getIntMappingType());
+                LOG.error("Invalid accountId type '{}'", connObjectKeyItem.getIntMappingType());
         }
 
         return result;
     }
 
-    private List<Long> search(final SearchCond searchCond, final SubjectType type) {
+    private List<Long> search(final SearchCond searchCond, final AnyTypeKind type) {
         final List<Long> result = new ArrayList<>();
 
-        List<Subject<?, ?, ?>> subjects = searchDAO.search(
+        List<Any<?, ?, ?>> anys = searchDAO.search(
                 SyncopeConstants.FULL_ADMIN_REALMS, searchCond, Collections.<OrderByClause>emptyList(), type);
-        for (Subject<?, ?, ?> subject : subjects) {
-            result.add(subject.getKey());
+        for (Any<?, ?, ?> any : anys) {
+            result.add(any.getKey());
         }
 
         return result;
     }
 
     private List<Long> findByCorrelationRule(
-            final ConnectorObject connObj, final SyncCorrelationRule rule, final SubjectType type) {
+            final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
 
         return search(rule.getSearchCond(connObj), type);
     }
 
-    private List<Long> findByAttributableSearch(
+    private List<Long> findByAnySearch(
             final ConnectorObject connObj,
             final List<String> altSearchSchemas,
-            final ExternalResource resource,
-            final AttributableUtils attrUtils) {
+            final Provision provision,
+            final AnyUtils anyUtils) {
 
         // search for external attribute's name/value of each specified name
-        final Map<String, Attribute> extValues = new HashMap<>();
+        Map<String, Attribute> extValues = new HashMap<>();
 
-        for (MappingItem item : attrUtils.getMappingItems(resource, MappingPurpose.SYNCHRONIZATION)) {
+        for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
             extValues.put(item.getIntAttrName(), connObj.getAttributeByName(item.getExtAttrName()));
         }
 
@@ -285,7 +306,7 @@ public class SyncUtils {
             if ("key".equalsIgnoreCase(schema)
                     || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
 
-                SubjectCond cond = new SubjectCond();
+                AnyCond cond = new AnyCond();
                 cond.setSchema(schema);
                 cond.setType(type);
                 cond.setExpression(expression);
@@ -305,24 +326,13 @@ public class SyncUtils {
                     : SearchCond.getAndCond(searchCond, nodeCond);
         }
 
-        return search(searchCond, SubjectType.valueOf(attrUtils.getType().name()));
+        return search(searchCond, anyUtils.getAnyTypeKind());
     }
 
-    private SyncCorrelationRule getCorrelationRule(final AttributableType type, final SyncPolicySpec policySpec) {
-        String clazz;
-
-        switch (type) {
-            case USER:
-                clazz = policySpec.getUserJavaRule();
-                break;
-            case GROUP:
-                clazz = policySpec.getGroupJavaRule();
-                break;
-            case MEMBERSHIP:
-            case CONFIGURATION:
-            default:
-                clazz = null;
-        }
+    private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
+        String clazz = policySpec.getItem(provision.getAnyType().getKey()) == null
+                ? null
+                : policySpec.getItem(provision.getAnyType().getKey()).getJavaRule();
 
         SyncCorrelationRule res = null;
 
@@ -337,22 +347,10 @@ public class SyncUtils {
         return res;
     }
 
-    private List<String> getAltSearchSchemas(final AttributableType type, final SyncPolicySpec policySpec) {
-        List<String> result = Collections.emptyList();
-
-        switch (type) {
-            case USER:
-                result = policySpec.getuAltSearchSchemas();
-                break;
-            case GROUP:
-                result = policySpec.getrAltSearchSchemas();
-                break;
-            case MEMBERSHIP:
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
+    private List<String> getAltSearchSchemas(final Provision provision, final SyncPolicySpec policySpec) {
+        return policySpec.getItem(provision.getAnyType().getKey()) == null
+                ? Collections.<String>emptyList()
+                : policySpec.getItem(provision.getAnyType().getKey()).getAltSearchSchemas();
     }
 
     /**
@@ -360,33 +358,33 @@ public class SyncUtils {
      *
      * @param uid for finding by account id
      * @param connObj for finding by attribute value
-     * @param resource external resource
-     * @param attrUtils attributable util
+     * @param provision external resource
+     * @param anyUtils any util
      * @return list of matching users / groups
      */
     public List<Long> findExisting(
             final String uid,
             final ConnectorObject connObj,
-            final ExternalResource resource,
-            final AttributableUtils attrUtils) {
+            final Provision provision,
+            final AnyUtils anyUtils) {
 
         SyncPolicySpec syncPolicySpec = null;
-        if (resource.getSyncPolicy() != null) {
-            syncPolicySpec = resource.getSyncPolicy().getSpecification(SyncPolicySpec.class);
+        if (provision.getResource().getSyncPolicy() != null) {
+            syncPolicySpec = provision.getResource().getSyncPolicy().getSpecification(SyncPolicySpec.class);
         }
 
         SyncCorrelationRule syncRule = null;
         List<String> altSearchSchemas = null;
 
         if (syncPolicySpec != null) {
-            syncRule = getCorrelationRule(attrUtils.getType(), syncPolicySpec);
-            altSearchSchemas = getAltSearchSchemas(attrUtils.getType(), syncPolicySpec);
+            syncRule = getCorrelationRule(provision, syncPolicySpec);
+            altSearchSchemas = getAltSearchSchemas(provision, syncPolicySpec);
         }
 
         return syncRule == null ? altSearchSchemas == null || altSearchSchemas.isEmpty()
-                ? findByAccountIdItem(uid, resource, attrUtils)
-                : findByAttributableSearch(connObj, altSearchSchemas, resource, attrUtils)
-                : findByCorrelationRule(connObj, syncRule, SubjectType.valueOf(attrUtils.getType().name()));
+                ? findByConnObjectKeyItem(uid, provision, anyUtils)
+                : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
+                : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
     }
 
     public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
index 87d72e6..dc1ea5a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
@@ -22,15 +22,14 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
@@ -41,31 +40,31 @@ import org.identityconnectors.framework.common.objects.Uid;
 public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.USER);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
     }
 
     @Override
-    protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
-        final UserTO before = userDataBinder.getUserTO(sbj.getKey());
+    protected Any<?, ?, ?> deprovision(final Any<?, ?, ?> sbj) {
+        UserTO before = userDataBinder.getUserTO(sbj.getKey());
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getUserDeleteTasks(before.getKey(),
                 Collections.singleton(profile.getTask().getResource().getKey()), noPropResources));
 
-        return userDAO.authFetch(before.getKey());
+        return userDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final UserTO before = userDataBinder.getUserTO(sbj.getKey());
+    protected Any<?, ?, ?> provision(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        UserTO before = userDataBinder.getUserTO(sbj.getKey());
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
-        final PropagationByResource propByRes = new PropagationByResource();
+        PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getUserCreateTasks(
@@ -74,15 +73,14 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
                 propByRes,
                 null,
                 Collections.unmodifiableCollection(before.getVirAttrs()),
-                Collections.unmodifiableCollection(before.getMemberships()),
                 noPropResources));
 
-        return userDAO.authFetch(before.getKey());
+        return userDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
-        final UserMod userMod = new UserMod();
+    protected Any<?, ?, ?> link(final Any<?, ?, ?> sbj, final Boolean unlink) {
+        UserMod userMod = new UserMod();
         userMod.setKey(sbj.getKey());
 
         if (unlink) {
@@ -93,12 +91,12 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
 
         uwfAdapter.update(userMod);
 
-        return userDAO.authFetch(userMod.getKey());
+        return userDAO.authFind(userMod.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
-        final UserMod userMod = new UserMod();
+    protected Any<?, ?, ?> unassign(final Any<?, ?, ?> sbj) {
+        UserMod userMod = new UserMod();
         userMod.setKey(sbj.getKey());
         userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         uwfAdapter.update(userMod);
@@ -106,8 +104,8 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final UserMod userMod = new UserMod();
+    protected Any<?, ?, ?> assign(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        UserMod userMod = new UserMod();
         userMod.setKey(sbj.getKey());
         userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
         uwfAdapter.update(userMod);
@@ -115,12 +113,12 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected String getName(final Subject<?, ?, ?> subject) {
+    protected String getName(final Any<?, ?, ?> subject) {
         return User.class.cast(subject).getUsername();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return userDataBinder.getUserTO(key);
         } catch (Exception e) {
@@ -130,9 +128,9 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected Subject<?, ?, ?> getSubject(final long key) {
+    protected Any<?, ?, ?> getAny(final long key) {
         try {
-            return userDAO.authFetch(key);
+            return userDAO.authFind(key);
         } catch (Exception e) {
             LOG.warn("Error retrieving user {}", key, e);
             return null;
@@ -140,14 +138,13 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected ConnectorObject getRemoteObject(final String accountId) {
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
         ConnectorObject obj = null;
-
         try {
-            final Uid uid = new Uid(accountId);
+            Uid uid = new Uid(connObjectKey);
 
             obj = profile.getConnector().getObject(
-                    ObjectClass.ACCOUNT,
+                    objectClass,
                     uid,
                     profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
 
@@ -155,13 +152,9 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", accountId, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
-        return obj;
-    }
 
-    @Override
-    protected Mapping<?> getMapping() {
-        return profile.getTask().getResource().getUmapping();
+        return obj;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
index d32a855..3e99286 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
@@ -21,13 +21,13 @@ package org.apache.syncope.core.provisioning.java.sync;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
 import org.identityconnectors.framework.common.objects.SyncDelta;
@@ -35,17 +35,17 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler implements UserSyncResultHandler {
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.USER);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.USER);
     }
 
     @Override
-    protected String getName(final AbstractSubjectTO subjectTO) {
+    protected String getName(final AnyTO subjectTO) {
         return UserTO.class.cast(subjectTO).getUsername();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return userDataBinder.getUserTO(key);
         } catch (Exception e) {
@@ -55,20 +55,7 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
     }
 
     @Override
-    protected AbstractSubjectMod getSubjectMod(
-            final AbstractSubjectTO subjectTO, final SyncDelta delta) {
-
-        return connObjectUtils.getAttributableMod(subjectTO.getKey(),
-                delta.getObject(),
-                subjectTO,
-                profile.getTask(),
-                getAttributableUtils());
-    }
-
-    @Override
-    protected AbstractSubjectTO doCreate(
-            final AbstractSubjectTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
-
+    protected AnyTO doCreate(final AnyTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
         UserTO userTO = UserTO.class.cast(subjectTO);
 
         Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
@@ -81,8 +68,8 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
     }
 
     @Override
-    protected AbstractSubjectTO doLink(
-            final AbstractSubjectTO before,
+    protected AnyTO doLink(
+            final AnyTO before,
             final ProvisioningResult result,
             final boolean unlink) {
 
@@ -99,13 +86,13 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
     }
 
     @Override
-    protected AbstractSubjectTO doUpdate(
-            final AbstractSubjectTO before,
-            final AbstractSubjectMod subjectMod,
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyMod anyMod,
             final SyncDelta delta,
             final ProvisioningResult result) {
 
-        final UserMod userMod = UserMod.class.cast(subjectMod);
+        final UserMod userMod = UserMod.class.cast(anyMod);
         final Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
 
         Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(userMod, before.getKey(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
index 9ddc91d..138fee3 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
@@ -18,12 +18,10 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import org.apache.syncope.core.provisioning.java.ConnectorManager;
-
 import static org.junit.Assert.assertEquals;
 
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
index a8305a6..51245e4 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
@@ -27,15 +27,17 @@ import java.util.HashSet;
 import java.util.Set;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationMode;
+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.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+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.MappingItem;
 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,6 +47,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class ResourceDataBinderTest extends AbstractTest {
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
@@ -55,12 +60,14 @@ public class ResourceDataBinderTest extends AbstractTest {
 
     @Test
     public void issue42() {
-        UPlainSchema userId = plainSchemaDAO.find("userId", UPlainSchema.class);
+        PlainSchema userId = plainSchemaDAO.find("userId");
 
         Set<MappingItem> beforeUserIdMappings = new HashSet<>();
         for (ExternalResource res : resourceDAO.findAll()) {
-            if (res.getUmapping() != null) {
-                for (MappingItem mapItem : res.getUmapping().getItems()) {
+            if (res.getProvision(anyTypeDAO.findUser()) != null
+                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (userId.getKey().equals(mapItem.getIntAttrName())) {
                         beforeUserIdMappings.add(mapItem);
                     }
@@ -74,8 +81,12 @@ public class ResourceDataBinderTest extends AbstractTest {
         resourceTO.setPropagationMode(PropagationMode.ONE_PHASE);
         resourceTO.setEnforceMandatoryCondition(true);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType("user");
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
-        resourceTO.setUmapping(mapping);
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntAttrName("userId");
@@ -84,13 +95,13 @@ public class ResourceDataBinderTest extends AbstractTest {
         item.setAccountid(true);
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         ExternalResource resource = resourceDataBinder.create(resourceTO);
         resource = resourceDAO.save(resource);
         assertNotNull(resource);
-        assertNotNull(resource.getUmapping());
-        assertEquals(1, resource.getUmapping().getItems().size());
+        assertNotNull(resource.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertEquals(1, resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
 
         resourceDAO.flush();
 
@@ -98,12 +109,14 @@ public class ResourceDataBinderTest extends AbstractTest {
         assertNotNull(actual);
         assertEquals(resource, actual);
 
-        userId = plainSchemaDAO.find("userId", UPlainSchema.class);
+        userId = plainSchemaDAO.find("userId");
 
         Set<MappingItem> afterUserIdMappings = new HashSet<>();
         for (ExternalResource res : resourceDAO.findAll()) {
-            if (res.getUmapping() != null) {
-                for (MappingItem mapItem : res.getUmapping().getItems()) {
+            if (res.getProvision(anyTypeDAO.findUser()) != null
+                    && res.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : res.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (userId.getKey().equals(mapItem.getIntAttrName())) {
                         afterUserIdMappings.add(mapItem);
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index ee4825e..c8e42a1 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -34,8 +34,8 @@ import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.apache.syncope.core.logic.GroupLogic;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -65,7 +65,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
     }
 
     @Override
-    public PagedResult<GroupTO> list(final SubjectListQuery listQuery) {
+    public PagedResult<GroupTO> list(final AnyListQuery listQuery) {
         CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
 
             @Override
@@ -91,7 +91,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
     }
 
     @Override
-    public PagedResult<GroupTO> search(final SubjectSearchQuery searchQuery) {
+    public PagedResult<GroupTO> search(final AnySearchQuery searchQuery) {
         CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
 
             @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index dfc4391..7ace502 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -23,17 +23,18 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.syncope.common.lib.wrap.AnyKey;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.core.logic.AbstractResourceAssociator;
+import org.apache.syncope.core.logic.AnyObjectLogic;
 import org.apache.syncope.core.logic.ResourceLogic;
 import org.apache.syncope.core.logic.GroupLogic;
 import org.apache.syncope.core.logic.UserLogic;
@@ -47,6 +48,9 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     private ResourceLogic logic;
 
     @Autowired
+    private AnyObjectLogic anyObjectLogic;
+
+    @Autowired
     private UserLogic userLogic;
 
     @Autowired
@@ -83,8 +87,8 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public ConnObjectTO getConnectorObject(final String resourceKey, final SubjectType type, final Long key) {
-        return logic.getConnectorObject(resourceKey, type, key);
+    public ConnObjectTO readConnObject(final String resourceKey, final String anyTypeKey, final Long key) {
+        return logic.readConnObject(resourceKey, anyTypeKey, key);
     }
 
     @Override
@@ -93,17 +97,20 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public BulkActionResult bulkDeassociation(final String resourceKey, final SubjectType subjectType,
-            final ResourceDeassociationActionType type, final List<SubjectKey> subjectKeys) {
+    public BulkActionResult bulkDeassociation(
+            final String resourceKey, final String anyTypeKey, final ResourceDeassociationActionType type,
+            final List<AnyKey> keys) {
 
-        AbstractResourceAssociator<? extends AbstractAttributableTO> associator = subjectType == SubjectType.USER
+        AbstractResourceAssociator<? extends AnyTO> associator = anyTypeKey.equalsIgnoreCase(AnyTypeKind.USER.name())
                 ? userLogic
-                : groupLogic;
+                : anyTypeKey.equalsIgnoreCase(AnyTypeKind.GROUP.name())
+                        ? groupLogic
+                        : anyObjectLogic;
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult res = new BulkActionResult();
 
-        for (SubjectKey key : subjectKeys) {
-            final Set<String> resources = Collections.singleton(resourceKey);
+        for (AnyKey key : keys) {
+            Set<String> resources = Collections.singleton(resourceKey);
             try {
                 switch (type) {
                     case DEPROVISION:
@@ -123,7 +130,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
 
                 res.add(key, BulkActionResult.Status.SUCCESS);
             } catch (Exception e) {
-                LOG.warn("While executing {} on {} {}", type, subjectType, key.getElement(), e);
+                LOG.warn("While executing {} on {} {}", type, anyTypeKey, key.getElement(), e);
                 res.add(key, BulkActionResult.Status.FAILURE);
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
index 3082c94..c8d2f26 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
@@ -22,7 +22,6 @@ import java.net.URI;
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.SchemaService;
@@ -37,10 +36,8 @@ public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaServ
     private SchemaLogic logic;
 
     @Override
-    public <T extends AbstractSchemaTO> Response create(final AttributableType attrType, final SchemaType schemaType,
-            final T schemaTO) {
-
-        T created = logic.create(attrType, schemaType, schemaTO);
+    public <T extends AbstractSchemaTO> Response create(final SchemaType schemaType, final T schemaTO) {
+        T created = logic.create(schemaType, schemaTO);
 
         URI location = uriInfo.getAbsolutePathBuilder().path(created.getKey()).build();
         return Response.created(location).
@@ -49,27 +46,25 @@ public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaServ
     }
 
     @Override
-    public void delete(final AttributableType attrType, final SchemaType schemaType, final String schemaKey) {
-        logic.delete(attrType, schemaType, schemaKey);
+    public void delete(final SchemaType schemaType, final String schemaKey) {
+        logic.delete(schemaType, schemaKey);
     }
 
     @Override
-    public <T extends AbstractSchemaTO> List<T> list(final AttributableType attrType, final SchemaType schemaType) {
-        return logic.list(attrType, schemaType);
+    public <T extends AbstractSchemaTO> List<T> list(final SchemaType schemaType) {
+        return logic.list(schemaType);
     }
 
     @Override
-    public <T extends AbstractSchemaTO> T read(final AttributableType attrType, final SchemaType schemaType,
-            final String schemaKey) {
-
-        return logic.read(attrType, schemaType, schemaKey);
+    public <T extends AbstractSchemaTO> T read(final SchemaType schemaType, final String schemaKey) {
+        return logic.read(schemaType, schemaKey);
     }
 
     @Override
-    public <T extends AbstractSchemaTO> void update(final AttributableType attrType, final SchemaType schemaType,
-            final String schemaKey, final T schemaTO) {
+    public <T extends AbstractSchemaTO> void update(
+            final SchemaType schemaType, final String schemaKey, final T schemaTO) {
 
         schemaTO.setKey(schemaKey);
-        logic.update(attrType, schemaType, schemaTO);
+        logic.update(schemaType, schemaTO);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index a758993..919cb0a 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -38,8 +38,8 @@ import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 import org.apache.syncope.common.rest.api.service.UserService;
 import org.apache.syncope.core.logic.UserLogic;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -83,7 +83,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public PagedResult<UserTO> list(final SubjectListQuery listQuery) {
+    public PagedResult<UserTO> list(final AnyListQuery listQuery) {
         CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
 
             @Override
@@ -109,7 +109,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public PagedResult<UserTO> search(final SubjectSearchQuery searchQuery) {
+    public PagedResult<UserTO> search(final AnySearchQuery searchQuery) {
         CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
 
             @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java
index 30229a6..5b82db0 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java
@@ -23,7 +23,7 @@ import java.io.OutputStream;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.StreamingOutput;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.WorkflowService;
 import org.apache.syncope.core.logic.WorkflowLogic;
@@ -37,7 +37,7 @@ public class WorkflowServiceImpl extends AbstractServiceImpl implements Workflow
     private WorkflowLogic logic;
 
     @Override
-    public Response exportDefinition(final SubjectType kind) {
+    public Response exportDefinition(final AnyTypeKind kind) {
         final MediaType accept =
                 messageContext.getHttpHeaders().getAcceptableMediaTypes().contains(MediaType.APPLICATION_JSON_TYPE)
                         ? MediaType.APPLICATION_JSON_TYPE
@@ -47,8 +47,10 @@ public class WorkflowServiceImpl extends AbstractServiceImpl implements Workflow
 
             @Override
             public void write(final OutputStream os) throws IOException {
-                if (kind == SubjectType.USER) {
+                if (kind == AnyTypeKind.USER) {
                     logic.exportUserDefinition(accept, os);
+                } else if (kind == AnyTypeKind.ANY_OBJECT) {
+                    logic.exportAnyObjectDefinition(accept, os);
                 } else {
                     logic.exportGroupDefinition(accept, os);
                 }
@@ -61,13 +63,15 @@ public class WorkflowServiceImpl extends AbstractServiceImpl implements Workflow
     }
 
     @Override
-    public Response exportDiagram(final SubjectType kind) {
+    public Response exportDiagram(final AnyTypeKind kind) {
         StreamingOutput sout = new StreamingOutput() {
 
             @Override
             public void write(final OutputStream os) throws IOException {
-                if (kind == SubjectType.USER) {
+                if (kind == AnyTypeKind.USER) {
                     logic.exportUserDiagram(os);
+                } else if (kind == AnyTypeKind.ANY_OBJECT) {
+                    logic.exportAnyObjectDiagram(os);
                 } else {
                     logic.exportGroupDiagram(os);
                 }
@@ -80,14 +84,16 @@ public class WorkflowServiceImpl extends AbstractServiceImpl implements Workflow
     }
 
     @Override
-    public void importDefinition(final SubjectType kind, final String definition) {
+    public void importDefinition(final AnyTypeKind kind, final String definition) {
         final MediaType contentType =
                 messageContext.getHttpHeaders().getMediaType().equals(MediaType.APPLICATION_JSON_TYPE)
                         ? MediaType.APPLICATION_JSON_TYPE
                         : MediaType.APPLICATION_XML_TYPE;
 
-        if (kind == SubjectType.USER) {
+        if (kind == AnyTypeKind.USER) {
             logic.importUserDefinition(contentType, definition);
+        } else if (kind == AnyTypeKind.ANY_OBJECT) {
+            logic.importAnyObjectDefinition(contentType, definition);
         } else {
             logic.importGroupDefinition(contentType, definition);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 4c89caf..938081f 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -439,7 +439,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     @Override
     public WorkflowResult<Long> execute(final UserTO userTO, final String taskId) {
-        User user = userDAO.authFetch(userTO.getKey());
+        User user = userDAO.authFind(userTO.getKey());
 
         final Map<String, Object> variables = new HashMap<>();
         variables.put(USER_TO, userTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserQueryImpl.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserQueryImpl.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserQueryImpl.java
index 506455f..caa8a05 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserQueryImpl.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserQueryImpl.java
@@ -30,8 +30,8 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 
 public class SyncopeUserQueryImpl implements UserQuery {
 
@@ -152,10 +152,9 @@ public class SyncopeUserQueryImpl implements UserQuery {
                 result = Collections.<User>emptyList();
             } else {
                 result = new ArrayList<>();
-                List<Membership> memberships = groupDAO.findMemberships(group);
-                User user;
-                for (Membership membership : memberships) {
-                    user = fromSyncopeUser(membership.getUser());
+                List<UMembership> memberships = groupDAO.findUMemberships(group);
+                for (UMembership membership : memberships) {
+                    User user = fromSyncopeUser(membership.getLeftEnd());
                     if (!result.contains(user)) {
                         result.add(user);
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java
new file mode 100644
index 0000000..4927388
--- /dev/null
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.workflow.api;
+
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+
+/**
+ * Interface for calling underlying workflow implementations.
+ */
+public interface AnyObjectWorkflowAdapter extends WorkflowAdapter {
+
+    /**
+     * Create a anyObject.
+     *
+     * @param anyObjectTO anyObject to be created and whether to propagate it as active
+     * @return anyObject just created
+     */
+    WorkflowResult<Long> create(AnyObjectTO anyObjectTO);
+
+    /**
+     * Execute a task on a anyObject.
+     *
+     * @param anyObjectTO anyObject to be subject to task
+     * @param taskId to be executed
+     * @return anyObject just updated
+     */
+    WorkflowResult<Long> execute(AnyObjectTO anyObjectTO, String taskId);
+
+    /**
+     * Update a anyObject.
+     *
+     * @param anyObjectMod modification set to be performed
+     * @return anyObject just updated and propagations to be performed
+     */
+    WorkflowResult<Long> update(AnyObjectMod anyObjectMod);
+
+    /**
+     * Delete a anyObject.
+     *
+     * @param anyObjectKey anyObject to be deleted
+     */
+    void delete(Long anyObjectKey);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
index 0c92d66..faf954a 100644
--- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.workflow.api;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import java.io.OutputStream;
 import java.util.List;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.to.WorkflowFormTO;
 
 public interface WorkflowAdapter {
@@ -79,7 +79,7 @@ public interface WorkflowAdapter {
     WorkflowFormTO getForm(String workflowId);
 
     /**
-     * Claim a form for a given user.
+     * Claim a form for a given object.
      *
      * @param taskId Workflow task to which the form is associated
      * @return updated form
@@ -90,7 +90,7 @@ public interface WorkflowAdapter {
      * Submit a form.
      *
      * @param form to be submitted
-     * @return user updated by this form submit
+     * @return object updated by this form submit
      */
-    WorkflowResult<? extends AbstractAttributableMod> submitForm(WorkflowFormTO form);
+    WorkflowResult<? extends AnyMod> submitForm(WorkflowFormTO form);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
index 30bfae6..97a8b1f 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
@@ -49,13 +49,13 @@ public abstract class AbstractGroupWorkflowAdapter implements GroupWorkflowAdapt
 
     @Override
     public WorkflowResult<Long> update(final GroupMod groupMod) {
-        return doUpdate(groupDAO.authFetch(groupMod.getKey()), groupMod);
+        return doUpdate(groupDAO.authFind(groupMod.getKey()), groupMod);
     }
 
     protected abstract void doDelete(Group group);
 
     @Override
     public void delete(final Long groupKey) {
-        doDelete(groupDAO.authFetch(groupKey));
+        doDelete(groupDAO.authFind(groupKey));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
index b1c3b4a..fc75987 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
@@ -62,21 +62,21 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
 
     @Override
     public WorkflowResult<Long> activate(final Long userKey, final String token) {
-        return doActivate(userDAO.authFetch(userKey), token);
+        return doActivate(userDAO.authFind(userKey), token);
     }
 
     protected abstract WorkflowResult<Pair<UserMod, Boolean>> doUpdate(User user, UserMod userMod);
 
     @Override
     public WorkflowResult<Pair<UserMod, Boolean>> update(final UserMod userMod) {
-        return doUpdate(userDAO.authFetch(userMod.getKey()), userMod);
+        return doUpdate(userDAO.authFind(userMod.getKey()), userMod);
     }
 
     protected abstract WorkflowResult<Long> doSuspend(User user);
 
     @Override
     public WorkflowResult<Long> suspend(final Long userKey) {
-        return suspend(userDAO.authFetch(userKey));
+        return suspend(userDAO.authFind(userKey));
     }
 
     @Override
@@ -91,7 +91,7 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
 
     @Override
     public WorkflowResult<Long> reactivate(final Long userKey) {
-        final User user = userDAO.authFetch(userKey);
+        final User user = userDAO.authFind(userKey);
 
         // reset failed logins
         user.setFailedLogins(0);
@@ -106,20 +106,20 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter
 
     @Override
     public void requestPasswordReset(final Long userKey) {
-        doRequestPasswordReset(userDAO.authFetch(userKey));
+        doRequestPasswordReset(userDAO.authFind(userKey));
     }
 
     protected abstract void doConfirmPasswordReset(User user, String token, String password);
 
     @Override
     public void confirmPasswordReset(final Long userKey, final String token, final String password) {
-        doConfirmPasswordReset(userDAO.authFetch(userKey), token, password);
+        doConfirmPasswordReset(userDAO.authFind(userKey), token, password);
     }
 
     protected abstract void doDelete(User user);
 
     @Override
     public void delete(final Long userKey) {
-        doDelete(userDAO.authFetch(userKey));
+        doDelete(userDAO.authFind(userKey));
     }
 }


[12/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
new file mode 100644
index 0000000..9d253da
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
@@ -0,0 +1,500 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.cxf.ws.addressing.v200403.Relationship;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+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.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnySearchTest extends AbstractTest {
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    @Test
+    public void anyObjectMatch() {
+        AnyObject anyObject = anyObjectDAO.find(1L);
+        assertNotNull(anyObject);
+        
+        RelationshipCond cond = new RelationshipCond();
+        cond.setAnyObjectKey(2L);
+        assertTrue(searchDAO.matches(anyObject, SearchCond.getLeafCond(cond), AnyTypeKind.ANY_OBJECT));
+    }
+
+    @Test
+    public void userMatch() {
+        User user = userDAO.find(1L);
+        assertNotNull(user);
+
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroupKey(5L);
+        assertFalse(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), AnyTypeKind.USER));
+
+        groupCond.setGroupKey(1L);
+        assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), AnyTypeKind.USER));
+
+        RoleCond roleCond = new RoleCond();
+        roleCond.setRoleKey(3L);
+        assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(roleCond), AnyTypeKind.USER));
+    }
+
+    @Test
+    public void groupMatch() {
+        Group group = groupDAO.find(1L);
+        assertNotNull(group);
+
+        AttributeCond attrCond = new AttributeCond();
+        attrCond.setSchema("show");
+        attrCond.setType(AttributeCond.Type.ISNOTNULL);
+
+        assertTrue(searchDAO.matches(group, SearchCond.getLeafCond(attrCond), AnyTypeKind.GROUP));
+    }
+
+    @Test
+    public void searchWithLikeCondition() {
+        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("%o%");
+
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroupKey(1L);
+
+        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+        loginDateCond.setSchema("loginDate");
+        loginDateCond.setExpression("2009-05-26");
+
+        SearchCond subCond = SearchCond.getAndCond(
+                SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(groupCond));
+
+        assertTrue(subCond.isValid());
+
+        SearchCond cond = SearchCond.getAndCond(subCond, SearchCond.getLeafCond(loginDateCond));
+
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchWithNotCondition() {
+        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("Giuseppe Verdi");
+
+        SearchCond cond = SearchCond.getNotLeafCond(fullnameLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(4, users.size());
+
+        Set<Long> ids = new HashSet<>(users.size());
+        for (User user : users) {
+            ids.add(user.getKey());
+        }
+        assertTrue(ids.contains(1L));
+        assertTrue(ids.contains(3L));
+    }
+
+    @Test
+    public void searchByBoolean() {
+        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(Long.valueOf(4L), users.get(0).getKey());
+    }
+
+    @Test
+    public void searchByPageAndSize() {
+        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("%o%");
+
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroupKey(1L);
+
+        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+        loginDateCond.setSchema("loginDate");
+        loginDateCond.setExpression("2009-05-26");
+
+        SearchCond subCond = SearchCond.getAndCond(
+                SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(groupCond));
+
+        assertTrue(subCond.isValid());
+
+        SearchCond cond = SearchCond.getAndCond(subCond, SearchCond.getLeafCond(loginDateCond));
+
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                cond, 1, 2, Collections.<OrderByClause>emptyList(),
+                AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                cond, 2, 2, Collections.<OrderByClause>emptyList(),
+                AnyTypeKind.USER);
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+    }
+
+    @Test
+    public void searchByGroup() {
+        MembershipCond groupCond = new MembershipCond();
+        groupCond.setGroupKey(1L);
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(groupCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+
+        groupCond = new MembershipCond();
+        groupCond.setGroupKey(5L);
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getNotLeafCond(groupCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(5, users.size());
+    }
+
+    @Test
+    public void searchByRole() {
+        RoleCond roleCond = new RoleCond();
+        roleCond.setRoleKey(3L);
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(roleCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchByIsNull() {
+        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.ISNULL);
+        coolLeafCond.setSchema("cool");
+
+        List<User> users = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, SearchCond.getLeafCond(coolLeafCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(4, users.size());
+
+        coolLeafCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
+        coolLeafCond.setSchema("cool");
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(coolLeafCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchByResource() {
+        ResourceCond ws2 = new ResourceCond();
+        ws2.setResourceName("ws-target-resource-2");
+
+        ResourceCond ws1 = new ResourceCond();
+        ws1.setResourceName("ws-target-resource-list-mappings-2");
+
+        SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), SearchCond.getLeafCond(ws1));
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchByBooleanSubjectCond() {
+        AttributeCond booleanCond = new AttributeCond(AnyCond.Type.EQ);
+        booleanCond.setSchema("show");
+        booleanCond.setExpression("true");
+
+        List<Group> matchingGroups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(booleanCond), AnyTypeKind.GROUP);
+        assertNotNull(matchingGroups);
+        assertFalse(matchingGroups.isEmpty());
+    }
+
+    @Test
+    public void searchByUsernameAndKey() {
+        AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.LIKE);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("%ini");
+
+        AnyCond idRightCond = new AnyCond(AnyCond.Type.LT);
+        idRightCond.setSchema("key");
+        idRightCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getAndCond(
+                SearchCond.getLeafCond(usernameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, AnyTypeKind.USER);
+
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.size());
+        assertEquals("rossini", matchingUsers.iterator().next().getUsername());
+        assertEquals(1L, matchingUsers.iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByGroupNameAndKey() {
+        AnyCond groupNameLeafCond = new AnyCond(AnyCond.Type.EQ);
+        groupNameLeafCond.setSchema("name");
+        groupNameLeafCond.setExpression("root");
+
+        AnyCond idRightCond = new AnyCond(AnyCond.Type.LT);
+        idRightCond.setSchema("key");
+        idRightCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getAndCond(
+                SearchCond.getLeafCond(groupNameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        assertTrue(searchCondition.isValid());
+
+        List<Group> matchingGroups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, AnyTypeKind.GROUP);
+
+        assertNotNull(matchingGroups);
+        assertEquals(1, matchingGroups.size());
+        assertEquals("root", matchingGroups.iterator().next().getName());
+        assertEquals(1L, matchingGroups.iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByUsernameAndFullname() {
+        AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.EQ);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("rossini");
+
+        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
+        idRightCond.setSchema("fullname");
+        idRightCond.setExpression("Giuseppe V%");
+
+        SearchCond searchCondition = SearchCond.getOrCond(
+                SearchCond.getLeafCond(usernameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, AnyTypeKind.USER);
+        assertNotNull(matchingUsers);
+        assertEquals(2, matchingUsers.size());
+    }
+
+    @Test
+    public void searchById() {
+        AnyCond idLeafCond = new AnyCond(AnyCond.Type.LT);
+        idLeafCond.setSchema("id");
+        idLeafCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+        assertEquals(1L, users.iterator().next().getKey(), 0);
+
+        idLeafCond = new AnyCond(AnyCond.Type.LT);
+        idLeafCond.setSchema("id");
+        idLeafCond.setExpression("4");
+
+        searchCondition = SearchCond.getNotLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
+
+            @Override
+            public boolean evaluate(User user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void userOrderBy() {
+        AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.EQ);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("rossini");
+        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
+        idRightCond.setSchema("fullname");
+        idRightCond.setExpression("Giuseppe V%");
+        SearchCond searchCondition = SearchCond.getOrCond(
+                SearchCond.getLeafCond(usernameLeafCond), SearchCond.getLeafCond(idRightCond));
+
+        List<OrderByClause> orderByClauses = new ArrayList<>();
+        OrderByClause orderByClause = new OrderByClause();
+        orderByClause.setField("username");
+        orderByClause.setDirection(OrderByClause.Direction.DESC);
+        orderByClauses.add(orderByClause);
+        orderByClause = new OrderByClause();
+        orderByClause.setField("fullname");
+        orderByClause.setDirection(OrderByClause.Direction.ASC);
+        orderByClauses.add(orderByClause);
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, orderByClauses, AnyTypeKind.USER);
+        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER),
+                users.size());
+    }
+
+    @Test
+    public void groupOrderBy() {
+        AnyCond idLeafCond = new AnyCond(AnyCond.Type.LIKE);
+        idLeafCond.setSchema("name");
+        idLeafCond.setExpression("%r");
+        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        OrderByClause orderByClause = new OrderByClause();
+        orderByClause.setField("name");
+
+        List<Group> groups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, Collections.singletonList(orderByClause), AnyTypeKind.GROUP);
+        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, AnyTypeKind.GROUP),
+                groups.size());
+    }
+
+    @Test
+    public void issue202() {
+        ResourceCond ws2 = new ResourceCond();
+        ws2.setResourceName("ws-target-resource-2");
+
+        ResourceCond ws1 = new ResourceCond();
+        ws1.setResourceName("ws-target-resource-list-mappings-1");
+
+        SearchCond searchCondition =
+                SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), SearchCond.getNotLeafCond(ws1));
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
+
+            @Override
+            public boolean evaluate(User user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void issue242() {
+        AnyCond cond = new AnyCond(AttributeCond.Type.LIKE);
+        cond.setSchema("id");
+        cond.setExpression("test%");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(cond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE46() {
+        AnyCond cond = new AnyCond(AttributeCond.Type.LIKE);
+        cond.setSchema("username");
+        cond.setExpression("%ossin%");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(cond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void issueSYNCOPE433() {
+        AttributeCond isNullCond = new AttributeCond(AttributeCond.Type.ISNULL);
+        isNullCond.setSchema("loginDate");
+
+        AnyCond likeCond = new AnyCond(AttributeCond.Type.LIKE);
+        likeCond.setSchema("username");
+        likeCond.setExpression("%ossin%");
+
+        SearchCond searchCond = SearchCond.getOrCond(
+                SearchCond.getLeafCond(isNullCond), SearchCond.getLeafCond(likeCond));
+
+        Integer count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCond, AnyTypeKind.USER);
+        assertNotNull(count);
+        assertTrue(count > 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
index 4ad4dd0..a0d12a6 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
@@ -29,7 +29,7 @@ import java.util.Arrays;
 import java.util.Random;
 import javax.validation.ValidationException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 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.PlainAttrDAO;
@@ -37,10 +37,10 @@ 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.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.crypto.codec.Base64;
@@ -78,7 +78,7 @@ public class AttrTest extends AbstractTest {
     public void save() throws ClassNotFoundException {
         User user = userDAO.find(1L);
 
-        UPlainSchema emailSchema = plainSchemaDAO.find("email", UPlainSchema.class);
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
         assertNotNull(emailSchema);
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
@@ -87,15 +87,15 @@ public class AttrTest extends AbstractTest {
 
         Exception thrown = null;
         try {
-            attribute.addValue("john.doe@gmail.com", attrUtilsFactory.getInstance(AttributableType.USER));
-            attribute.addValue("mario.rossi@gmail.com", attrUtilsFactory.getInstance(AttributableType.USER));
+            attribute.add("john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+            attribute.add("mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
         } catch (ValidationException e) {
             thrown = e;
         }
         assertNull("no validation exception expected here ", thrown);
 
         try {
-            attribute.addValue("http://www.apache.org", attrUtilsFactory.getInstance(AttributableType.USER));
+            attribute.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
         } catch (ValidationException e) {
             thrown = e;
         }
@@ -105,8 +105,9 @@ public class AttrTest extends AbstractTest {
     @Test
     public void saveWithEnum() throws ClassNotFoundException {
         User user = userDAO.find(1L);
+        assertNotNull(user);
 
-        UPlainSchema gender = plainSchemaDAO.find("gender", UPlainSchema.class);
+        PlainSchema gender = plainSchemaDAO.find("gender");
         assertNotNull(gender);
         assertNotNull(gender.getType());
         assertNotNull(gender.getEnumerationValues());
@@ -114,18 +115,18 @@ public class AttrTest extends AbstractTest {
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
         attribute.setSchema(gender);
         attribute.setOwner(user);
-        user.addPlainAttr(attribute);
+        user.add(attribute);
 
         Exception thrown = null;
 
         try {
-            attribute.addValue("A", attrUtilsFactory.getInstance(AttributableType.USER));
+            attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
         } catch (ValidationException e) {
             thrown = e;
         }
         assertNotNull("validation exception expected here ", thrown);
 
-        attribute.addValue("M", attrUtilsFactory.getInstance(AttributableType.USER));
+        attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
 
         InvalidEntityException iee = null;
         try {
@@ -140,10 +141,10 @@ public class AttrTest extends AbstractTest {
     public void validateAndSave() {
         User user = userDAO.find(1L);
 
-        final UPlainSchema emailSchema = plainSchemaDAO.find("email", UPlainSchema.class);
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
         assertNotNull(emailSchema);
 
-        final UPlainSchema fullnameSchema = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
         assertNotNull(fullnameSchema);
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
@@ -156,7 +157,7 @@ public class AttrTest extends AbstractTest {
 
         attribute.setUniqueValue(uauv);
 
-        user.addPlainAttr(attribute);
+        user.add(attribute);
 
         InvalidEntityException iee = null;
         try {
@@ -169,23 +170,23 @@ public class AttrTest extends AbstractTest {
         // for attribute
         assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
         // for uauv
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidUPlainSchema));
+        assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema));
     }
 
     @Test
     public void saveWithEncrypted() throws Exception {
         User user = userDAO.find(1L);
 
-        final UPlainSchema obscureSchema = plainSchemaDAO.find("obscure", UPlainSchema.class);
+        PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
         assertNotNull(obscureSchema);
         assertNotNull(obscureSchema.getSecretKey());
         assertNotNull(obscureSchema.getCipherAlgorithm());
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
         attribute.setSchema(obscureSchema);
-        attribute.addValue("testvalue", attrUtilsFactory.getInstance(AttributableType.USER));
+        attribute.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
         attribute.setOwner(user);
-        user.addPlainAttr(attribute);
+        user.add(attribute);
 
         userDAO.save(user);
 
@@ -200,7 +201,7 @@ public class AttrTest extends AbstractTest {
     public void saveWithBinary() throws UnsupportedEncodingException {
         User user = userDAO.find(1L);
 
-        final UPlainSchema photoSchema = plainSchemaDAO.find("photo", UPlainSchema.class);
+        PlainSchema photoSchema = plainSchemaDAO.find("photo");
         assertNotNull(photoSchema);
         assertNotNull(photoSchema.getMimeType());
 
@@ -210,9 +211,9 @@ public class AttrTest extends AbstractTest {
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
         attribute.setSchema(photoSchema);
-        attribute.addValue(photoB64Value, attrUtilsFactory.getInstance(AttributableType.USER));
+        attribute.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
         attribute.setOwner(user);
-        user.addPlainAttr(attribute);
+        user.add(attribute);
 
         userDAO.save(user);
 
@@ -229,7 +230,7 @@ public class AttrTest extends AbstractTest {
 
         plainAttrDAO.delete(attribute.getKey(), UPlainAttr.class);
 
-        UPlainSchema schema = plainSchemaDAO.find(attrSchemaName, UPlainSchema.class);
+        PlainSchema schema = plainSchemaDAO.find(attrSchemaName);
         assertNotNull("user attribute schema deleted when deleting values", schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java
index 2539a44..606c417 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java
@@ -25,14 +25,15 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 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.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -60,10 +61,21 @@ public class ConfTest extends AbstractTest {
         assertNull(conf);
     }
 
+    private void add(final CPlainAttr newAttr, final String value) {
+        JPACPlainAttrValue attrValue;
+        if (newAttr.getSchema().isUniqueConstraint()) {
+            attrValue = new JPACPlainAttrValue();
+            ((PlainAttrUniqueValue) attrValue).setSchema(newAttr.getSchema());
+        } else {
+            attrValue = new JPACPlainAttrValue();
+        }
+        newAttr.add(value, attrValue);
+    }
+
     @Test
     public void setAndDelete() {
         // 1. create CSChema
-        CPlainSchema useless = entityFactory.newEntity(CPlainSchema.class);
+        PlainSchema useless = entityFactory.newEntity(PlainSchema.class);
         useless.setKey("useless");
         useless.setType(AttrSchemaType.Date);
         useless.setConversionPattern("yyyy-MM-dd");
@@ -72,7 +84,7 @@ public class ConfTest extends AbstractTest {
         // 2. create conf
         CPlainAttr newConf = entityFactory.newEntity(CPlainAttr.class);
         newConf.setSchema(useless);
-        newConf.addValue("2014-06-20", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+        add(newConf, "2014-06-20");
         confDAO.save(newConf);
 
         CPlainAttr actual = confDAO.find("useless");
@@ -80,7 +92,7 @@ public class ConfTest extends AbstractTest {
 
         // 3. update conf
         newConf.getValues().clear();
-        newConf.addValue("2014-06-20", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+        add(newConf, "2014-06-20");
         confDAO.save(newConf);
 
         actual = confDAO.find("useless");
@@ -94,7 +106,7 @@ public class ConfTest extends AbstractTest {
     @Test
     public void issueSYNCOPE418() {
         try {
-            CPlainSchema failing = entityFactory.newEntity(CPlainSchema.class);
+            PlainSchema failing = entityFactory.newEntity(PlainSchema.class);
             failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
             failing.setType(AttrSchemaType.String);
             plainSchemaDAO.save(failing);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.java
index 67765b1..11381e5 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.java
@@ -27,21 +27,13 @@ import static org.junit.Assert.assertTrue;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
@@ -59,9 +51,6 @@ public class DerAttrTest extends AbstractTest {
     private UserDAO userDAO;
 
     @Autowired
-    private MembershipDAO membershipDAO;
-
-    @Autowired
     private GroupDAO groupDAO;
 
     @Autowired
@@ -81,7 +70,7 @@ public class DerAttrTest extends AbstractTest {
 
     @Test
     public void saveUDerAttribute() {
-        UDerSchema cnSchema = derSchemaDAO.find("cn", UDerSchema.class);
+        DerSchema cnSchema = derSchemaDAO.find("cn");
         assertNotNull(cnSchema);
 
         User owner = userDAO.find(3L);
@@ -104,38 +93,18 @@ public class DerAttrTest extends AbstractTest {
     }
 
     @Test
-    public void saveMDerAttribute() {
-        Membership owner = membershipDAO.find(1L);
-        assertNotNull("did not get expected user", owner);
-
-        MDerAttr derAttr = entityFactory.newEntity(MDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setTemplate(owner.getGroup().getAttrTemplate(MDerAttrTemplate.class, "mderiveddata"));
-
-        derAttr = derAttrDAO.save(derAttr);
-        assertNotNull(derAttr.getTemplate());
-
-        MDerAttr actual = derAttrDAO.find(derAttr.getKey(), MDerAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(derAttr, actual);
+    public void saveGDerAttribute() {
+        DerSchema schema = derSchemaDAO.find("rderiveddata");
+        assertNotNull(schema);
 
-        MPlainAttrValue sx = owner.getPlainAttr("mderived_sx").getValues().iterator().next();
-        MPlainAttrValue dx = owner.getPlainAttr("mderived_dx").getValues().iterator().next();
-
-        assertEquals(sx.getValue() + "-" + dx.getValue(), derAttr.getValue(owner.getPlainAttrs()));
-    }
-
-    @Test
-    public void saveRDerAttribute() {
         Group owner = groupDAO.find(1L);
         assertNotNull("did not get expected user", owner);
 
         GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
         derAttr.setOwner(owner);
-        derAttr.setTemplate(owner.getAttrTemplate(GDerAttrTemplate.class, "rderiveddata"));
+        derAttr.setSchema(schema);
 
         derAttr = derAttrDAO.save(derAttr);
-        assertNotNull(derAttr.getTemplate());
 
         GDerAttr actual = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
         assertNotNull("expected save to work", actual);
@@ -150,27 +119,27 @@ public class DerAttrTest extends AbstractTest {
     @Test
     public void delete() {
         UDerAttr attribute = derAttrDAO.find(100L, UDerAttr.class);
-        String attributeSchemaName = attribute.getSchema().getKey();
+        String schemaName = attribute.getSchema().getKey();
 
         derAttrDAO.delete(attribute.getKey(), UDerAttr.class);
 
         UDerAttr actual = derAttrDAO.find(100L, UDerAttr.class);
         assertNull("delete did not work", actual);
 
-        UDerSchema attributeSchema = derSchemaDAO.find(attributeSchemaName, UDerSchema.class);
-        assertNotNull("user derived attribute schema deleted " + "when deleting values", attributeSchema);
+        DerSchema attributeSchema = derSchemaDAO.find(schemaName);
+        assertNotNull("user derived attribute schema deleted when deleting values", attributeSchema);
     }
 
     @Test
     public void issueSYNCOPE134User() {
-        UDerSchema sderived = entityFactory.newEntity(UDerSchema.class);
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
         sderived.setKey("sderived");
         sderived.setExpression("status + ' - ' + username + ' - ' + creationDate + '[' + failedLogins + ']'");
 
         sderived = derSchemaDAO.save(sderived);
         derSchemaDAO.flush();
 
-        UDerSchema actual = derSchemaDAO.find("sderived", UDerSchema.class);
+        DerSchema actual = derSchemaDAO.find("sderived");
         assertNotNull("expected save to work", actual);
         assertEquals(sderived, actual);
 
@@ -196,30 +165,25 @@ public class DerAttrTest extends AbstractTest {
 
     @Test
     public void issueSYNCOPE134Group() {
-        GDerSchema sderived = entityFactory.newEntity(GDerSchema.class);
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
         sderived.setKey("sderived");
         sderived.setExpression("name");
 
         sderived = derSchemaDAO.save(sderived);
         derSchemaDAO.flush();
 
-        GDerSchema actual = derSchemaDAO.find("sderived", GDerSchema.class);
+        DerSchema actual = derSchemaDAO.find("sderived");
         assertNotNull("expected save to work", actual);
         assertEquals(sderived, actual);
 
         Group owner = groupDAO.find(7L);
         assertNotNull("did not get expected group", owner);
 
-        GDerAttrTemplate template = entityFactory.newEntity(GDerAttrTemplate.class);
-        template.setSchema(sderived);
-        owner.getAttrTemplates(GDerAttrTemplate.class).add(template);
-
         GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
         derAttr.setOwner(owner);
-        derAttr.setTemplate(owner.getAttrTemplate(GDerAttrTemplate.class, sderived.getKey()));
+        derAttr.setSchema(sderived);
 
         derAttr = derAttrDAO.save(derAttr);
-        assertNotNull(derAttr.getTemplate());
         derAttrDAO.flush();
 
         derAttr = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
@@ -230,43 +194,4 @@ public class DerAttrTest extends AbstractTest {
         assertFalse(value.isEmpty());
         assertTrue(value.startsWith("managingDirector"));
     }
-
-    @Test
-    public void issueSYNCOPE134Memb() {
-        MDerSchema mderived = entityFactory.newEntity(MDerSchema.class);
-        mderived.setKey("mderived");
-        mderived.setExpression("key");
-
-        mderived = derSchemaDAO.save(mderived);
-        derSchemaDAO.flush();
-
-        MDerSchema actual = derSchemaDAO.find("mderived", MDerSchema.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(mderived, actual);
-
-        Membership owner = membershipDAO.find(4L);
-        assertNotNull("did not get expected membership", owner);
-
-        MDerAttrTemplate template = entityFactory.newEntity(MDerAttrTemplate.class);
-        template.setSchema(mderived);
-        owner.getGroup().getAttrTemplates(MDerAttrTemplate.class).add(template);
-
-        derSchemaDAO.flush();
-
-        MDerAttr derAttr = entityFactory.newEntity(MDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setTemplate(owner.getGroup().getAttrTemplate(MDerAttrTemplate.class, mderived.getKey()));
-
-        derAttr = derAttrDAO.save(derAttr);
-        assertNotNull(derAttr.getTemplate());
-        derAttrDAO.flush();
-
-        derAttr = derAttrDAO.find(derAttr.getKey(), MDerAttr.class);
-        assertNotNull("expected save to work", derAttr);
-
-        String value = derAttr.getValue(owner.getPlainAttrs());
-        assertNotNull(value);
-        assertFalse(value.isEmpty());
-        assertTrue(value.equalsIgnoreCase("4"));
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java
index 8b4090b..b123513 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java
@@ -25,13 +25,10 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.List;
-import org.apache.syncope.common.lib.types.AttributableType;
 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.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,52 +42,52 @@ public class DerSchemaTest extends AbstractTest {
 
     @Test
     public void findAll() {
-        List<UDerSchema> list = derSchemaDAO.findAll(UDerSchema.class);
-        assertEquals(3, list.size());
+        List<DerSchema> list = derSchemaDAO.findAll();
+        assertEquals(9, list.size());
     }
 
     @Test
     public void findByName() {
-        UDerSchema attributeSchema = derSchemaDAO.find("cn", UDerSchema.class);
+        DerSchema attributeSchema = derSchemaDAO.find("cn");
         assertNotNull("did not find expected derived attribute schema", attributeSchema);
     }
 
     @Test
     public void save() {
-        UDerSchema derivedAttributeSchema = entityFactory.newEntity(UDerSchema.class);
+        DerSchema derivedAttributeSchema = entityFactory.newEntity(DerSchema.class);
         derivedAttributeSchema.setKey("cn2");
         derivedAttributeSchema.setExpression("firstname surname");
 
         derSchemaDAO.save(derivedAttributeSchema);
 
-        UDerSchema actual = derSchemaDAO.find("cn2", UDerSchema.class);
+        DerSchema actual = derSchemaDAO.find("cn2");
         assertNotNull("expected save to work", actual);
         assertEquals(derivedAttributeSchema, actual);
     }
 
     @Test
     public void delete() {
-        UDerSchema cn = derSchemaDAO.find("cn", UDerSchema.class);
+        DerSchema cn = derSchemaDAO.find("cn");
         assertNotNull(cn);
 
-        derSchemaDAO.delete(cn.getKey(), attrUtilsFactory.getInstance(AttributableType.USER));
+        derSchemaDAO.delete(cn.getKey());
 
-        DerSchema actual = derSchemaDAO.find("cn", UDerSchema.class);
+        DerSchema actual = derSchemaDAO.find("cn");
         assertNull("delete did not work", actual);
 
         // ------------- //
-        GDerSchema rderiveddata = derSchemaDAO.find("rderiveddata", GDerSchema.class);
+        DerSchema rderiveddata = derSchemaDAO.find("rderiveddata");
         assertNotNull(rderiveddata);
 
-        derSchemaDAO.delete(rderiveddata.getKey(), attrUtilsFactory.getInstance(AttributableType.GROUP));
+        derSchemaDAO.delete(rderiveddata.getKey());
 
-        actual = derSchemaDAO.find("rderiveddata", GDerSchema.class);
+        actual = derSchemaDAO.find("rderiveddata");
         assertNull("delete did not work", actual);
     }
 
     @Test
     public void issueSYNCOPE418() {
-        UDerSchema schema = entityFactory.newEntity(UDerSchema.class);
+        DerSchema schema = entityFactory.newEntity(DerSchema.class);
         schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/MembershipTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/MembershipTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/MembershipTest.java
deleted file mode 100644
index a623b14..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/MembershipTest.java
+++ /dev/null
@@ -1,84 +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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class MembershipTest extends AbstractTest {
-
-    @Autowired
-    private MembershipDAO membershipDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Test
-    public void findAll() {
-        List<Membership> list = membershipDAO.findAll();
-        assertEquals(7, list.size());
-    }
-
-    @Test
-    public void find() {
-        Membership membership = membershipDAO.find(1L);
-        assertNotNull("did not find expected membership", membership);
-    }
-
-    @Test
-    public void save() {
-        User user = userDAO.find(4L);
-        Group group = groupDAO.find(1L);
-
-        Membership membership = entityFactory.newEntity(Membership.class);
-        membership.setUser(user);
-        membership.setGroup(group);
-
-        membership = membershipDAO.save(membership);
-
-        Membership actual = membershipDAO.find(membership.getKey());
-        assertNotNull("expected save to work", actual);
-    }
-
-    @Test
-    public void delete() {
-        Membership membership = membershipDAO.find(4L);
-        membershipDAO.delete(membership.getKey());
-
-        Membership actual = membershipDAO.find(4L);
-        assertNull("delete did not work", actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java
index 8b545b8..df629ff 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java
@@ -24,7 +24,9 @@ import static org.junit.Assert.assertNull;
 
 import java.util.List;
 import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
@@ -35,6 +37,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class NotificationTest extends AbstractTest {
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private NotificationDAO notificationDAO;
 
     @Test
@@ -43,7 +48,7 @@ public class NotificationTest extends AbstractTest {
         assertNotNull(notification);
         assertNotNull(notification.getEvents());
         assertFalse(notification.getEvents().isEmpty());
-        assertNotNull(notification.getUserAbout());
+        assertNotNull(notification.getAbout(anyTypeDAO.findUser()));
         assertNotNull(notification.getRecipients());
 
     }
@@ -60,9 +65,13 @@ public class NotificationTest extends AbstractTest {
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("save");
 
-        notification.setUserAbout("fake search condition");
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set("fake search condition");
 
-        notification.setRecipients("fake search condition");
+        notification.setRecipients("fake recipients");
 
         notification.setRecipientAttrName("email");
         notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
@@ -87,7 +96,11 @@ public class NotificationTest extends AbstractTest {
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("save");
 
-        notification.setUserAbout("fake search condition");
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set("fake search condition");
 
         notification.setRecipients("fake search condition");
 
@@ -112,7 +125,11 @@ public class NotificationTest extends AbstractTest {
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
 
-        notification.setGroupAbout("fake search condition");
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set("fake search condition");
 
         notification.setRecipientAttrName("email");
         notification.setRecipientAttrType(IntMappingType.UserPlainSchema);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
index 27f587f..967a6be 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
@@ -28,13 +28,11 @@ import static org.junit.Assert.fail;
 import java.util.List;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 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.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,35 +46,29 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void findAll() {
-        List<UPlainSchema> userList = plainSchemaDAO.findAll(UPlainSchema.class);
-        assertEquals(15, userList.size());
-
-        List<GPlainSchema> groupList = plainSchemaDAO.findAll(GPlainSchema.class);
-        assertEquals(5, groupList.size());
+        List<PlainSchema> schemas = plainSchemaDAO.findAll();
+        assertEquals(40, schemas.size());
     }
 
     @Test
     public void findByName() {
-        UPlainSchema schema = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        PlainSchema schema = plainSchemaDAO.find("fullname");
         assertNotNull("did not find expected attribute schema", schema);
     }
 
     @Test
     public void findAttrs() {
-        List<GPlainSchema> schemas = plainSchemaDAO.findAll(GPlainSchema.class);
-        assertNotNull(schemas);
-        assertFalse(schemas.isEmpty());
-
-        for (GPlainSchema schema : schemas) {
-            List<GPlainAttr> attrs = plainSchemaDAO.findAttrs(schema, GPlainAttr.class);
-            assertNotNull(attrs);
-            assertFalse(attrs.isEmpty());
-        }
+        PlainSchema schema = plainSchemaDAO.find("icon");
+        assertNotNull(schema);
+
+        List<GPlainAttr> attrs = plainSchemaDAO.findAttrs(schema, GPlainAttr.class);
+        assertNotNull(attrs);
+        assertFalse(attrs.isEmpty());
     }
 
     @Test
     public void save() {
-        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setKey("secondaryEmail");
         schema.setType(AttrSchemaType.String);
         schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
@@ -85,14 +77,14 @@ public class PlainSchemaTest extends AbstractTest {
 
         plainSchemaDAO.save(schema);
 
-        UPlainSchema actual = plainSchemaDAO.find("secondaryEmail", UPlainSchema.class);
+        PlainSchema actual = plainSchemaDAO.find("secondaryEmail");
         assertNotNull("expected save to work", actual);
         assertEquals(schema, actual);
     }
 
     @Test(expected = InvalidEntityException.class)
     public void saveNonValid() {
-        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setKey("secondaryEmail");
         schema.setType(AttrSchemaType.String);
         schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
@@ -105,7 +97,7 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void checkForEnumType() {
-        GPlainSchema schema = entityFactory.newEntity(GPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setType(AttrSchemaType.Enum);
         schema.setKey("color");
 
@@ -122,7 +114,7 @@ public class PlainSchemaTest extends AbstractTest {
 
         plainSchemaDAO.save(schema);
 
-        GPlainSchema actual = plainSchemaDAO.find(schema.getKey(), GPlainSchema.class);
+        PlainSchema actual = plainSchemaDAO.find(schema.getKey());
         assertNotNull(actual);
         assertNotNull(actual.getEnumerationKeys());
         assertFalse(actual.getEnumerationKeys().isEmpty());
@@ -130,24 +122,24 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test(expected = InvalidEntityException.class)
     public void saveInvalidSchema() {
-        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setKey("username");
         plainSchemaDAO.save(schema);
     }
 
     @Test
     public void delete() {
-        UPlainSchema fullnam = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        PlainSchema firstname = plainSchemaDAO.find("firstname");
 
-        plainSchemaDAO.delete(fullnam.getKey(), attrUtilsFactory.getInstance(AttributableType.USER));
+        plainSchemaDAO.delete(firstname.getKey());
 
-        UPlainSchema actual = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        PlainSchema actual = plainSchemaDAO.find("firstname");
         assertNull("delete did not work", actual);
     }
 
     @Test
     public void issueSYNCOPE418() {
-        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java
index 4267815..764f0ac 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java
@@ -27,7 +27,9 @@ import java.util.List;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
 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.PolicyDAO;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
@@ -40,6 +42,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class PolicyTest extends AbstractTest {
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private PolicyDAO policyDAO;
 
     @Test
@@ -80,11 +85,19 @@ public class PolicyTest extends AbstractTest {
         SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
 
         final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
-        final String syncRRuleName = "net.tirasa.sync.correlation.TirasaRRule";
+        final String syncGRuleName = "net.tirasa.sync.correlation.TirasaGRule";
 
         SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
-        syncPolicySpec.setUserJavaRule(syncURuleName);
-        syncPolicySpec.setGroupJavaRule(syncRRuleName);
+
+        SyncPolicySpecItem item = new SyncPolicySpecItem();
+        item.setAnyTypeKey(anyTypeDAO.findUser().getKey());
+        item.setJavaRule(syncURuleName);
+        syncPolicySpec.getItems().add(item);
+
+        item = new SyncPolicySpecItem();
+        item.setAnyTypeKey(anyTypeDAO.findGroup().getKey());
+        item.setJavaRule(syncGRuleName);
+        syncPolicySpec.getItems().add(item);
 
         policy.setSpecification(syncPolicySpec);
         policy.setDescription("Sync policy");
@@ -93,8 +106,10 @@ public class PolicyTest extends AbstractTest {
 
         assertNotNull(policy);
         assertEquals(PolicyType.SYNC, policy.getType());
-        assertEquals(syncURuleName, (policy.getSpecification(SyncPolicySpec.class)).getUserJavaRule());
-        assertEquals(syncRRuleName, (policy.getSpecification(SyncPolicySpec.class)).getGroupJavaRule());
+        assertEquals(syncURuleName,
+                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findUser().getKey()).getJavaRule());
+        assertEquals(syncGRuleName,
+                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findGroup().getKey()).getJavaRule());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
index a9340c3..ad6c37c 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
@@ -25,18 +25,21 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 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.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.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.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +51,9 @@ public class ResourceTest extends AbstractTest {
     @Autowired
     private ExternalResourceDAO resourceDAO;
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Test
     public void findById() {
         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
@@ -59,13 +65,16 @@ public class ResourceTest extends AbstractTest {
                 "net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
         assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connector.getBundleName());
 
-        assertFalse("no mapping specified", resource.getUmapping().getItems().isEmpty());
+        Mapping mapping = resource.getProvision(anyTypeDAO.findUser()).getMapping();
+        assertFalse("no mapping specified", mapping.getItems().isEmpty());
 
-        List<Long> mappingIds = new ArrayList<>();
-        for (UMappingItem item : resource.getUmapping().getItems()) {
-            mappingIds.add(item.getKey());
-        }
-        assertTrue(mappingIds.contains(100L));
+        assertTrue(CollectionUtils.exists(mapping.getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return 100 == item.getKey();
+            }
+        }));
     }
 
     @Test
@@ -83,10 +92,11 @@ public class ResourceTest extends AbstractTest {
     }
 
     @Test
-    public void getAccountId() {
+    public void getConnObjectKey() {
         ExternalResource resource = resourceDAO.find("ws-target-resource-2");
         assertNotNull(resource);
-        assertEquals("fullname", resource.getUmapping().getAccountIdItem().getIntAttrName());
+        assertEquals("fullname",
+                resource.getProvision(anyTypeDAO.findUser()).getMapping().getConnObjectKeyItem().getIntAttrName());
     }
 
     @Test
@@ -96,15 +106,21 @@ public class ResourceTest extends AbstractTest {
         resource.setPropagationPriority(2);
         resource.setPropagationPrimary(true);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
 
-        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
-        accountId.setExtAttrName("username");
-        accountId.setIntAttrName("fullname");
-        accountId.setIntMappingType(IntMappingType.UserId);
-        accountId.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(accountId);
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("fullname");
+        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(connObjectKey);
 
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
@@ -114,8 +130,8 @@ public class ResourceTest extends AbstractTest {
 
         assertNotNull(actual);
         assertNotNull(actual.getConnector());
-        assertNotNull(actual.getUmapping());
-        assertFalse(actual.getUmapping().getItems().isEmpty());
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertFalse(actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems().isEmpty());
         assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
         assertTrue(actual.isPropagationPrimary());
     }
@@ -128,13 +144,19 @@ public class ResourceTest extends AbstractTest {
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
 
-        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
-        accountId.setAccountid(true);
-        accountId.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.addItem(accountId);
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setConnObjectKey(true);
+        connObjectKey.setIntMappingType(IntMappingType.UserPlainSchema);
+        mapping.add(connObjectKey);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
@@ -142,20 +164,26 @@ public class ResourceTest extends AbstractTest {
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void saveInvalidAccountIdMapping() {
+    public void saveInvalidConnObjectKeyMapping() {
         ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
         resource.setKey("ws-target-resource-basic-save-invalid");
 
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
 
-        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
-        accountId.setAccountid(true);
-        accountId.setIntMappingType(IntMappingType.UserVirtualSchema);
-        mapping.setAccountIdItem(accountId);
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setConnObjectKey(true);
+        connObjectKey.setIntMappingType(IntMappingType.UserVirtualSchema);
+        mapping.setConnObjectKeyItem(connObjectKey);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
@@ -170,19 +198,25 @@ public class ResourceTest extends AbstractTest {
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
 
-        UMappingItem item = entityFactory.newEntity(UMappingItem.class);
-        item.setAccountid(true);
+        MappingItem item = entityFactory.newEntity(MappingItem.class);
+        item.setConnObjectKey(true);
         item.setIntAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.addItem(item);
+        mapping.add(item);
 
-        item = entityFactory.newEntity(UMappingItem.class);
+        item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("userId");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.addItem(item);
+        mapping.add(item);
 
         ExternalResource actual = resourceDAO.save(resource);
         assertNotNull(actual);
@@ -196,45 +230,49 @@ public class ResourceTest extends AbstractTest {
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
 
-        UMappingItem item = entityFactory.newEntity(UMappingItem.class);
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
+
+        MappingItem item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("fullname");
         item.setExtAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
-        item = entityFactory.newEntity(UMappingItem.class);
+        item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setIntMappingType(IntMappingType.GroupPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
-        item = entityFactory.newEntity(UMappingItem.class);
+        item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("mderiveddata");
         item.setExtAttrName("mderiveddata");
-        item.setIntMappingType(IntMappingType.MembershipDerivedSchema);
+        item.setIntMappingType(IntMappingType.AnyDerivedSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
         assertNotNull(actual);
 
         int items = 0;
-        for (UMappingItem mapItem : actual.getUmapping().getItems()) {
+        for (MappingItem mapItem : actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
             items++;
 
             if ("icon".equals(mapItem.getIntAttrName())) {
-                assertTrue(IntMappingType.contains(AttributableType.GROUP,
-                        mapItem.getIntMappingType().toString()));
+                assertTrue(IntMappingType.contains(AnyTypeKind.GROUP, mapItem.getIntMappingType().toString()));
             }
             if ("mderiveddata".equals(mapItem.getIntAttrName())) {
-                assertTrue(IntMappingType.contains(AttributableType.MEMBERSHIP,
-                        mapItem.getIntMappingType().toString()));
+                assertTrue(IntMappingType.contains(AnyTypeKind.ANY_OBJECT, mapItem.getIntMappingType().toString()));
             }
         }
         assertEquals(3, items);
@@ -272,15 +310,21 @@ public class ResourceTest extends AbstractTest {
         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
 
-        final UMappingItem item = entityFactory.newEntity(UMappingItem.class);
+        final MappingItem item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
         item.setIntMappingType(IntMappingType.GroupPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);


[18/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
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 46b51dc..8c6aaa7 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
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -30,39 +29,33 @@ import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 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.jpa.entity.JPADynGroupMembership;
-import org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 @Repository
-public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAttr> implements UserDAO {
+public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Autowired
     private GroupDAO groupDAO;
@@ -73,57 +66,60 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
-    @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
-
     @Override
-    protected Subject<UPlainAttr, UDerAttr, UVirAttr> findInternal(final Long key) {
-        return find(key);
+    protected AnyUtils init() {
+        return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
     }
 
     @Override
-    public User find(final Long key) {
-        TypedQuery<User> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAUser.class.getSimpleName() + " e WHERE e.id = :id", User.class);
-        query.setParameter("id", key);
+    protected void securityChecks(final User user) {
+        // Allows anonymous (during self-registration) and self (during self-update) to read own user,
+        // otherwise goes through security checks to see if required entitlements are owned
+        if (!AuthContextUtils.getAuthenticatedUsername().equals(anonymousUser)
+                && !AuthContextUtils.getAuthenticatedUsername().equals(user.getUsername())) {
 
-        User result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No user found with id {}", key, e);
-        }
+            Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.USER_READ);
+            boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {
 
-        return result;
+                @Override
+                public boolean evaluate(final String realm) {
+                    return user.getRealm().getFullPath().startsWith(realm);
+                }
+            });
+            if (authRealms == null || authRealms.isEmpty() || !authorized) {
+                throw new UnauthorizedException(AnyTypeKind.USER, user.getKey());
+            }
+        }
     }
 
+    @Transactional(readOnly = true)
     @Override
-    public User find(final String username) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
-                + " e WHERE e.username = :username", User.class);
-        query.setParameter("username", username);
+    public User authFind(final String username) {
+        if (username == null) {
+            throw new NotFoundException("Null username");
+        }
 
-        User result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No user found with username {}", username, e);
+        User user = find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
         }
 
-        return result;
+        securityChecks(user);
+
+        return user;
     }
 
     @Override
-    public User findByWorkflowId(final String workflowId) {
+    public User find(final String username) {
         TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
-                + " e WHERE e.workflowId = :workflowId", User.class);
-        query.setParameter("workflowId", workflowId);
+                + " e WHERE e.username = :username", User.class);
+        query.setParameter("username", username);
 
         User result = null;
         try {
             result = query.getSingleResult();
         } catch (NoResultException e) {
-            LOG.debug("No user found with workflow id {}", workflowId, e);
+            LOG.debug("No user found with username {}", username, e);
         }
 
         return result;
@@ -154,54 +150,10 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
         return query.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByAttrValue(final String schemaName, final UPlainAttrValue attrValue) {
-        return (List<User>) findByAttrValue(
-                schemaName, attrValue, attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public User findByAttrUniqueValue(final String schemaName, final UPlainAttrValue attrUniqueValue) {
-        return (User) findByAttrUniqueValue(schemaName, attrUniqueValue,
-                attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByDerAttrValue(final String schemaName, final String value) {
-        return (List<User>) findByDerAttrValue(
-                schemaName, value, attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByResource(final ExternalResource resource) {
-        return (List<User>) findByResource(resource, attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @Override
-    public final List<User> findAll(final Set<String> adminRealms, final int page, final int itemsPerPage) {
-        return findAll(adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList());
-    }
-
-    @Override
-    public List<User> findAll(final Set<String> adminRealms,
-            final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
-
-        return searchDAO.search(adminRealms, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.USER);
-    }
-
-    @Override
-    public final int count(final Set<String> adminRealms) {
-        return searchDAO.count(adminRealms, getAllMatchingCond(), SubjectType.USER);
-    }
-
     @Override
     public User save(final User user) {
         User merged = entityManager.merge(user);
-        for (VirAttr virAttr : merged.getVirAttrs()) {
+        for (UVirAttr virAttr : merged.getVirAttrs()) {
             virAttr.getValues().clear();
             virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues());
         }
@@ -213,93 +165,17 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     }
 
     @Override
-    public void delete(final Long key) {
-        User user = (User) findInternal(key);
-        if (user == null) {
-            return;
-        }
-
-        delete(user);
-    }
-
-    @Override
     public void delete(final User user) {
-        // Not calling membershipDAO.delete() here because it would try to save this user as well, thus going into
-        // ConcurrentModificationException
-        for (Membership membership : user.getMemberships()) {
-            membership.setUser(null);
-
-            groupDAO.save(membership.getGroup());
-            membership.setGroup(null);
-
-            entityManager.remove(membership);
-        }
-        user.getMemberships().clear();
-
         for (Role role : findDynRoleMemberships(user)) {
-            role.getDynMembership().removeUser(user);
+            role.getDynMembership().remove(user);
         }
         for (Group group : findDynGroupMemberships(user)) {
-            group.getDynMembership().removeUser(user);
+            group.getUDynMembership().remove(user);
         }
 
         entityManager.remove(user);
     }
 
-    private void securityChecks(final User user) {
-        // Allows anonymous (during self-registration) and self (during self-update) to read own user,
-        // otherwise goes through security checks to see if required entitlements are owned
-        if (!AuthContextUtils.getAuthenticatedUsername().equals(anonymousUser)
-                && !AuthContextUtils.getAuthenticatedUsername().equals(user.getUsername())) {
-
-            Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.USER_READ);
-            boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {
-
-                @Override
-                public boolean evaluate(final String realm) {
-                    return user.getRealm().getFullPath().startsWith(realm);
-                }
-            });
-            if (authRealms == null || authRealms.isEmpty() || !authorized) {
-                throw new UnauthorizedException(SubjectType.USER, user.getKey());
-            }
-        }
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public User authFetch(final Long key) {
-        if (key == null) {
-            throw new NotFoundException("Null user id");
-        }
-
-        User user = find(key);
-        if (user == null) {
-            throw new NotFoundException("User " + key);
-        }
-
-        securityChecks(user);
-
-        return user;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public User authFetch(final String username) {
-        if (username == null) {
-            throw new NotFoundException("Null username");
-        }
-
-        User user = find(username);
-        if (user == null) {
-            throw new NotFoundException("User " + username);
-        }
-
-        securityChecks(user);
-
-        return user;
-    }
-
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Role> findDynRoleMemberships(final User user) {
@@ -315,7 +191,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Override
     public List<Group> findDynGroupMemberships(final User user) {
         TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e.group FROM " + JPADynGroupMembership.class.getSimpleName()
+                "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);
 
@@ -332,11 +208,11 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Override
     public Collection<Group> findAllGroups(final User user) {
         return CollectionUtils.union(
-                CollectionUtils.collect(user.getMemberships(), new Transformer<Membership, Group>() {
+                CollectionUtils.collect(user.getMemberships(), new Transformer<UMembership, Group>() {
 
                     @Override
-                    public Group transform(final Membership input) {
-                        return input.getGroup();
+                    public Group transform(final UMembership input) {
+                        return input.getRightEnd();
                     }
                 }, new ArrayList<Group>()),
                 findDynGroupMemberships(user));

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 48a645a..3ef6791 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -21,51 +21,51 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AVirAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
 import org.springframework.stereotype.Repository;
 
 @Repository
-public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> implements VirAttrDAO {
+public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirAttrDAO {
 
-    public <T extends VirAttr> Class<? extends AbstractVirAttr> getJPAEntityReference(
+    public <T extends VirAttr<?>> Class<? extends AbstractVirAttr<?>> getJPAEntityReference(
             final Class<T> reference) {
 
         return GVirAttr.class.isAssignableFrom(reference)
                 ? JPAGVirAttr.class
-                : MVirAttr.class.isAssignableFrom(reference)
-                        ? JPAMVirAttr.class
+                : AVirAttr.class.isAssignableFrom(reference)
+                        ? JPAAVirAttr.class
                         : UVirAttr.class.isAssignableFrom(reference)
                                 ? JPAUVirAttr.class
                                 : null;
     }
 
     @Override
-    public <T extends VirAttr> T find(final Long key, final Class<T> reference) {
+    public <T extends VirAttr<?>> T find(final Long key, final Class<T> reference) {
         return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
     }
 
     @Override
-    public <T extends VirAttr> List<T> findAll(final Class<T> reference) {
+    public <T extends VirAttr<?>> List<T> findAll(final Class<T> reference) {
         TypedQuery<T> query = entityManager.createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
-    public <T extends VirAttr> T save(final T virAttr) {
+    public <T extends VirAttr<?>> T save(final T virAttr) {
         return entityManager.merge(virAttr);
     }
 
     @Override
-    public <T extends VirAttr> void delete(final Long key, final Class<T> reference) {
+    public <T extends VirAttr<?>> void delete(final Long key, final Class<T> reference) {
         T virAttr = find(key, reference);
         if (virAttr == null) {
             return;
@@ -76,9 +76,9 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> implements VirAttr
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T extends VirAttr> void delete(final T virAttr) {
+    public <T extends VirAttr<?>> void delete(final T virAttr) {
         if (virAttr.getOwner() != null) {
-            ((Attributable<?, ?, T>) virAttr.getOwner()).removeVirAttr(virAttr);
+            ((Any<?, ?, T>) virAttr.getOwner()).remove(virAttr);
         }
 
         entityManager.remove(virAttr);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
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 f0ce84b..ed4f6b6 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
@@ -20,25 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+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.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirSchema;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPAVirSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -49,44 +40,25 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
     private VirAttrDAO virAttrDAO;
 
     @Autowired
-    private AttrTemplateDAO<VirSchema> attrTemplateDAO;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
-    private <T extends VirSchema> Class<? extends AbstractVirSchema> getJPAEntityReference(final Class<T> reference) {
-        return GVirSchema.class.isAssignableFrom(reference)
-                ? JPAGVirSchema.class
-                : MVirSchema.class.isAssignableFrom(reference)
-                        ? JPAMVirSchema.class
-                        : UVirSchema.class.isAssignableFrom(reference)
-                                ? JPAUVirSchema.class
-                                : null;
-    }
-
     @Override
-    public <T extends VirSchema> T find(final String key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+    public VirSchema find(final String key) {
+        return entityManager.find(JPAVirSchema.class, key);
     }
 
     @Override
-    public <T extends VirSchema> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
-                "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+    public List<VirSchema> findAll() {
+        TypedQuery<VirSchema> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
         return query.getResultList();
     }
 
     @Override
-    public <T extends VirAttr> List<T> findAttrs(final VirSchema schema, final Class<T> reference) {
+    public <T extends VirAttr<?>> List<T> findAttrs(final VirSchema schema, final Class<T> reference) {
         final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPAVirAttrDAO) virAttrDAO).getJPAEntityReference(reference).getSimpleName()).
-                append(" e WHERE e.");
-        if (UVirAttr.class.isAssignableFrom(reference)) {
-            queryString.append("virSchema");
-        } else {
-            queryString.append("template.schema");
-        }
-        queryString.append("=:schema");
+                append(" e WHERE e.schema=:schema");
 
         TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
@@ -95,41 +67,28 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
     }
 
     @Override
-    public <T extends VirSchema> T save(final T virSchema) {
+    public VirSchema save(final VirSchema virSchema) {
         return entityManager.merge(virSchema);
     }
 
     @Override
-    public void delete(final String key, final AttributableUtils attributableUtil) {
-        final VirSchema schema = find(key, attributableUtil.virSchemaClass());
+    public void delete(final String key) {
+        final VirSchema schema = find(key);
         if (schema == null) {
             return;
         }
 
-        CollectionUtils.forAllDo(findAttrs(schema, attributableUtil.virAttrClass()), new Closure<VirAttr>() {
+        AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory();
+        for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
 
-            @Override
-            public void execute(final VirAttr input) {
-                virAttrDAO.delete(input.getKey(), attributableUtil.virAttrClass());
+            for (VirAttr<?> attr : findAttrs(schema, anyUtils.virAttrClass())) {
+                virAttrDAO.delete(attr.getKey(), anyUtils.virAttrClass());
             }
 
-        });
-
-        if (attributableUtil.getType() != AttributableType.USER) {
-            CollectionUtils.forAllDo(attrTemplateDAO.
-                    findBySchemaName(schema.getKey(), attributableUtil.virAttrTemplateClass()).iterator(),
-                    new Closure<Number>() {
-
-                        @Override
-                        public void execute(final Number input) {
-                            attrTemplateDAO.delete(input.longValue(), attributableUtil.virAttrTemplateClass());
-                        }
-
-                    });
+            resourceDAO.deleteMapping(key, anyUtils.virIntMappingType());
         }
 
-        resourceDAO.deleteMapping(key, attributableUtil.virIntMappingType(), UMappingItem.class);
-
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
index 11b3298..77be714 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
@@ -20,8 +20,8 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
 
 class SearchSupport {
 
@@ -47,10 +47,10 @@ class SearchSupport {
         }
     }
 
-    private final SubjectType subjectType;
+    private final AnyTypeKind anyTypeKind;
 
-    public SearchSupport(final SubjectType subjectType) {
-        this.subjectType = subjectType;
+    public SearchSupport(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
     public String fieldName(final AttrSchemaType attrSchemaType) {
@@ -88,15 +88,19 @@ class SearchSupport {
     public SearchView field() {
         String result = "";
 
-        switch (subjectType) {
-            case USER:
-            default:
-                result = "user_search";
+        switch (anyTypeKind) {
+            case ANY_OBJECT:
+                result = "anyObject_search";
                 break;
 
             case GROUP:
                 result = "group_search";
                 break;
+
+            case USER:
+            default:
+                result = "user_search";
+                break;
         }
 
         return new SearchView("sv", result);
@@ -106,12 +110,19 @@ class SearchSupport {
         return new SearchView("sva", field().name + "_attr");
     }
 
+    public SearchView relationship() {
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "m", field().name + "_" + kind + "relationship");
+    }
+
     public SearchView membership() {
-        return new SearchView("svm", field().name + "_membership");
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "m", field().name + "_" + kind + "membership");
     }
 
     public SearchView dyngroupmembership() {
-        return new SearchView("svdg", field().name + "_dyngroupmembership");
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "dgm", field().name + "_" + kind + "dyngroupmembership");
     }
 
     public SearchView role() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
new file mode 100644
index 0000000..161927c
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -0,0 +1,149 @@
+/*
+ * 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;
+
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+
+@MappedSuperclass
+public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>>
+        extends AbstractAnnotatedEntity<Long>
+        implements Any<P, D, V> {
+
+    private static final long serialVersionUID = -2666540708092702810L;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPARealm realm;
+
+    private String workflowId;
+
+    @Column(nullable = true)
+    private String status;
+
+    @Override
+    public Realm getRealm() {
+        return realm;
+    }
+
+    @Override
+    public void setRealm(final Realm realm) {
+        checkType(realm, JPARealm.class);
+        this.realm = (JPARealm) realm;
+    }
+
+    @Override
+    public String getWorkflowId() {
+        return workflowId;
+    }
+
+    @Override
+    public void setWorkflowId(final String workflowId) {
+        this.workflowId = workflowId;
+    }
+
+    @Override
+    public String getStatus() {
+        return status;
+    }
+
+    @Override
+    public void setStatus(final String status) {
+        this.status = status;
+    }
+
+    @Override
+    public P getPlainAttr(final String plainSchemaName) {
+        return CollectionUtils.find(getPlainAttrs(), new Predicate<P>() {
+
+            @Override
+            public boolean evaluate(final P plainAttr) {
+                return plainAttr != null && plainAttr.getSchema() != null
+                        && plainSchemaName.equals(plainAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    @Override
+    public D getDerAttr(final String derSchemaName) {
+        return CollectionUtils.find(getDerAttrs(), new Predicate<D>() {
+
+            @Override
+            public boolean evaluate(final D derAttr) {
+                return derAttr != null && derAttr.getSchema() != null
+                        && derSchemaName.equals(derAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    @Override
+    public V getVirAttr(final String virSchemaName) {
+        return CollectionUtils.find(getVirAttrs(), new Predicate<V>() {
+
+            @Override
+            public boolean evaluate(final V virAttr) {
+                return virAttr != null && virAttr.getSchema() != null
+                        && virSchemaName.equals(virAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    protected abstract List<JPAExternalResource> internalGetResources();
+
+    @Override
+    public boolean add(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        return internalGetResources().add((JPAExternalResource) resource);
+    }
+
+    @Override
+    public boolean remove(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        return internalGetResources().remove((JPAExternalResource) resource);
+    }
+
+    @Override
+    public List<String> getResourceNames() {
+        return CollectionUtils.collect(getResources(), new Transformer<ExternalResource, String>() {
+
+            @Override
+            public String transform(final ExternalResource input) {
+                return input.getKey();
+            }
+        }, new ArrayList<String>());
+    }
+
+    @Override
+    public List<? extends ExternalResource> getResources() {
+        return internalGetResources();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
deleted file mode 100644
index f2a32a1..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.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.jpa.entity;
-
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-
-public abstract class AbstractAttrTemplate<S extends Schema> extends AbstractEntity<Long> implements AttrTemplate<S> {
-
-    private static final long serialVersionUID = 4829112252713766666L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
deleted file mode 100644
index b2e2b34..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
+++ /dev/null
@@ -1,68 +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;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public abstract class AbstractAttributable<P extends PlainAttr, D extends DerAttr, V extends VirAttr>
-        extends AbstractAnnotatedEntity<Long> implements Attributable<P, D, V> {
-
-    private static final long serialVersionUID = -4801685541488201119L;
-
-    @Override
-    public P getPlainAttr(final String plainSchemaName) {
-        return CollectionUtils.find(getPlainAttrs(), new Predicate<P>() {
-
-            @Override
-            public boolean evaluate(final P plainAttr) {
-                return plainAttr != null && plainAttr.getSchema() != null
-                        && plainSchemaName.equals(plainAttr.getSchema().getKey());
-            }
-        });
-    }
-
-    @Override
-    public D getDerAttr(final String derSchemaName) {
-        return CollectionUtils.find(getDerAttrs(), new Predicate<D>() {
-
-            @Override
-            public boolean evaluate(final D derAttr) {
-                return derAttr != null && derAttr.getSchema() != null
-                        && derSchemaName.equals(derAttr.getSchema().getKey());
-            }
-        });
-    }
-
-    @Override
-    public V getVirAttr(final String virSchemaName) {
-        return CollectionUtils.find(getVirAttrs(), new Predicate<V>() {
-
-            @Override
-            public boolean evaluate(final V virAttr) {
-                return virAttr != null && virAttr.getSchema() != null
-                        && virSchemaName.equals(virAttr.getSchema().getKey());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
index ae2ec1b..60dae3c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
@@ -19,16 +19,21 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
 
 @MappedSuperclass
-public abstract class AbstractDerAttr extends AbstractEntity<Long> implements DerAttr {
+public abstract class AbstractDerAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements DerAttr<O> {
 
     private static final long serialVersionUID = 4740924251090424771L;
 
@@ -36,17 +41,32 @@ public abstract class AbstractDerAttr extends AbstractEntity<Long> implements De
     @GeneratedValue(strategy = GenerationType.AUTO)
     protected Long id;
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPADerSchema schema;
+
     @Override
     public Long getKey() {
         return id;
     }
 
+    @Override
+    public DerSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final DerSchema derSchema) {
+        checkType(derSchema, JPADerSchema.class);
+        this.schema = (JPADerSchema) derSchema;
+    }
+
     /**
      * @param attributes the set of attributes against which evaluate this derived attribute
      * @return the value of this derived attribute
      */
     @Override
-    public String getValue(final Collection<? extends PlainAttr> attributes) {
+    public String getValue(final Collection<? extends PlainAttr<?>> attributes) {
         return JexlUtils.evaluate(getSchema().getExpression(), getOwner(), attributes);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
deleted file mode 100644
index 3846b12..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
+++ /dev/null
@@ -1,41 +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;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-
-@MappedSuperclass
-public abstract class AbstractDerAttrTemplate<D extends DerSchema> extends AbstractAttrTemplate<D> {
-
-    private static final long serialVersionUID = 8871895736733379865L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
deleted file mode 100644
index 195f41d..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
+++ /dev/null
@@ -1,85 +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;
-
-import javax.persistence.Column;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@SchemaNameCheck
-public abstract class AbstractDerSchema extends AbstractEntity<String> implements DerSchema {
-
-    private static final long serialVersionUID = -6173643493348674060L;
-
-    @Id
-    private String name;
-
-    @Column(nullable = false)
-    private String expression;
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.name = key;
-    }
-
-    @Override
-    public String getExpression() {
-        return expression;
-    }
-
-    @Override
-    public void setExpression(final String expression) {
-        this.expression = expression;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return AttrSchemaType.String;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return Boolean.FALSE.toString().toLowerCase();
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return Boolean.TRUE;
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return Boolean.FALSE;
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return Boolean.FALSE;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
index 6e47b34..c5404e9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
@@ -18,15 +18,14 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import java.util.List;
 import javax.persistence.MappedSuperclass;
 import javax.validation.constraints.NotNull;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DynMembership;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 
 @MappedSuperclass
-public abstract class AbstractDynMembership extends AbstractEntity<Long> implements DynMembership {
+public abstract class AbstractDynMembership<A extends Any<?, ?, ?>>
+        extends AbstractEntity<Long> implements DynMembership<A> {
 
     private static final long serialVersionUID = 921821654690948787L;
 
@@ -43,23 +42,4 @@ public abstract class AbstractDynMembership extends AbstractEntity<Long> impleme
         this.fiql = fiql;
     }
 
-    protected abstract List<JPAUser> internalGetUsers();
-
-    @Override
-    public boolean addUser(final User user) {
-        checkType(user, JPAUser.class);
-        return internalGetUsers().add((JPAUser) user);
-    }
-
-    @Override
-    public boolean removeUser(final User user) {
-        checkType(user, JPAUser.class);
-        return internalGetUsers().remove((JPAUser) user);
-    }
-
-    @Override
-    public List<? extends User> getUsers() {
-        return internalGetUsers();
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
deleted file mode 100644
index 4481d3e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
+++ /dev/null
@@ -1,78 +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;
-
-import javax.persistence.Cacheable;
-import javax.persistence.MappedSuperclass;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-
-@MappedSuperclass
-@Cacheable
-public abstract class AbstractMapping<T extends MappingItem> extends AbstractEntity<Long> implements Mapping<T> {
-
-    private static final long serialVersionUID = 4316047254916259158L;
-
-    /**
-     * A JEXL expression for determining how to find the account id in external resource's space.
-     */
-    private String accountLink;
-
-    @Override
-    public String getAccountLink() {
-        return accountLink;
-    }
-
-    @Override
-    public void setAccountLink(final String accountLink) {
-        this.accountLink = accountLink;
-    }
-
-    @Override
-    public T getAccountIdItem() {
-        return CollectionUtils.find(getItems(), new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T item) {
-                return item.isAccountid();
-            }
-        });
-    }
-
-    protected boolean addAccountIdItem(final T accountIdItem) {
-        if (IntMappingType.UserVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.GroupVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.MembershipVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.Password == accountIdItem.getIntMappingType()) {
-
-            throw new IllegalArgumentException("Virtual attributes cannot be set as accountId");
-        }
-        if (IntMappingType.Password == accountIdItem.getIntMappingType()) {
-            throw new IllegalArgumentException("Password attributes cannot be set as accountId");
-        }
-
-        accountIdItem.setExtAttrName(accountIdItem.getExtAttrName());
-        accountIdItem.setAccountid(true);
-
-        return this.addItem(accountIdItem);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
deleted file mode 100644
index 98aab13..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
+++ /dev/null
@@ -1,190 +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;
-
-import javax.persistence.Basic;
-import javax.persistence.Cacheable;
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.MappedSuperclass;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-
-@MappedSuperclass
-@Cacheable
-public abstract class AbstractMappingItem extends AbstractEntity<Long> implements MappingItem {
-
-    private static final long serialVersionUID = 7383601853619332424L;
-
-    @Column(nullable = true)
-    private String intAttrName;
-
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private IntMappingType intMappingType;
-
-    /**
-     * Target resource's field to be mapped.
-     */
-    @Column(nullable = true)
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    @Column(nullable = false)
-    private String mandatoryCondition;
-
-    /**
-     * Specify if the mapped target resource's field is the key.
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer accountid;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer password;
-
-    /**
-     * Mapping purposes: SYNCHRONIZATION, PROPAGATION, BOTH.
-     */
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private MappingPurpose purpose;
-
-    public AbstractMappingItem() {
-        super();
-
-        mandatoryCondition = Boolean.FALSE.toString();
-
-        accountid = getBooleanAsInteger(false);
-        password = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
-    }
-
-    @Override
-    public String getIntAttrName() {
-        final String name;
-
-        switch (getIntMappingType()) {
-            case UserId:
-            case GroupId:
-            case MembershipId:
-                name = "id";
-                break;
-
-            case Username:
-                name = "username";
-                break;
-
-            case Password:
-                name = "password";
-                break;
-
-            case GroupName:
-                name = "groupName";
-                break;
-
-            case GroupOwnerSchema:
-                name = "groupOwnerSchema";
-                break;
-
-            default:
-                name = intAttrName;
-        }
-
-        return name;
-    }
-
-    @Override
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    @Override
-    public IntMappingType getIntMappingType() {
-        return intMappingType;
-    }
-
-    @Override
-    public void setIntMappingType(final IntMappingType intMappingType) {
-        this.intMappingType = intMappingType;
-    }
-
-    @Override
-    public boolean isAccountid() {
-        return isBooleanAsInteger(accountid);
-    }
-
-    @Override
-    public void setAccountid(final boolean accountid) {
-        this.accountid = getBooleanAsInteger(accountid);
-    }
-
-    @Override
-    public boolean isPassword() {
-        return isBooleanAsInteger(password);
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        this.password = getBooleanAsInteger(password);
-    }
-
-    @Override
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
index ff1efee..a93cc45 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
@@ -21,33 +21,45 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 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.jpa.validation.entity.PlainAttrCheck;
 
 @MappedSuperclass
 @PlainAttrCheck
-public abstract class AbstractPlainAttr extends AbstractEntity<Long> implements PlainAttr {
+public abstract class AbstractPlainAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements PlainAttr<O> {
 
     private static final long serialVersionUID = -9115431608821806124L;
 
-    protected abstract boolean addValue(PlainAttrValue attrValue);
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPAPlainSchema schema;
 
     @Override
-    public void addValue(final String value, final AttributableUtils attributableUtil) {
-        PlainAttrValue attrValue;
-        if (getSchema().isUniqueConstraint()) {
-            attrValue = attributableUtil.newPlainAttrUniqueValue();
-            ((PlainAttrUniqueValue) attrValue).setSchema(getSchema());
-        } else {
-            attrValue = attributableUtil.newPlainAttrValue();
-        }
+    public PlainSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
+    }
+
+    protected abstract boolean addForMultiValue(PlainAttrValue attrValue);
 
+    @Override
+    public void add(final String value, final PlainAttrValue attrValue) {
         attrValue.setAttr(this);
         getSchema().getValidator().validate(value, attrValue);
 
@@ -57,8 +69,21 @@ public abstract class AbstractPlainAttr extends AbstractEntity<Long> implements
             if (!getSchema().isMultivalue()) {
                 getValues().clear();
             }
-            addValue(attrValue);
+            addForMultiValue(attrValue);
+        }
+    }
+
+    @Override
+    public void add(final String value, final AnyUtils anyUtils) {
+        PlainAttrValue attrValue;
+        if (getSchema().isUniqueConstraint()) {
+            attrValue = anyUtils.newPlainAttrUniqueValue();
+            ((PlainAttrUniqueValue) attrValue).setSchema(getSchema());
+        } else {
+            attrValue = anyUtils.newPlainAttrValue();
         }
+
+        add(value, attrValue);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
deleted file mode 100644
index a6777a1..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.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.jpa.entity;
-
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-
-public abstract class AbstractPlainAttrTemplate<P extends PlainSchema> extends AbstractAttrTemplate<P> {
-
-    private static final long serialVersionUID = -943169893494860655L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
deleted file mode 100644
index d08ba1c..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
+++ /dev/null
@@ -1,272 +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;
-
-import java.lang.reflect.Constructor;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.Transient;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator;
-import org.apache.syncope.core.persistence.jpa.validation.entity.PlainSchemaCheck;
-import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@PlainSchemaCheck
-@SchemaNameCheck
-public abstract class AbstractPlainSchema extends AbstractEntity<String> implements PlainSchema {
-
-    private static final long serialVersionUID = -8621028596062054739L;
-
-    @Id
-    private String name;
-
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private AttrSchemaType type;
-
-    @Column(nullable = false)
-    private String mandatoryCondition;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer multivalue;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer uniqueConstraint;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer readonly;
-
-    @Column(nullable = true)
-    private String conversionPattern;
-
-    @Column(nullable = true)
-    private String validatorClass;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationValues;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationKeys;
-
-    @Column(nullable = true)
-    private String secretKey;
-
-    @Column(nullable = true)
-    @Enumerated(EnumType.STRING)
-    private CipherAlgorithm cipherAlgorithm;
-
-    @Column(nullable = true)
-    private String mimeType;
-
-    @Transient
-    private Validator validator;
-
-    public AbstractPlainSchema() {
-        super();
-
-        type = AttrSchemaType.String;
-        mandatoryCondition = Boolean.FALSE.toString();
-        multivalue = getBooleanAsInteger(false);
-        uniqueConstraint = getBooleanAsInteger(false);
-        readonly = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String name) {
-        this.name = name;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return type;
-    }
-
-    @Override
-    public void setType(final AttrSchemaType type) {
-        this.type = type;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String condition) {
-        this.mandatoryCondition = condition;
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return isBooleanAsInteger(multivalue);
-    }
-
-    @Override
-    public void setMultivalue(final boolean multivalue) {
-        this.multivalue = getBooleanAsInteger(multivalue);
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return isBooleanAsInteger(uniqueConstraint);
-    }
-
-    @Override
-    public void setUniqueConstraint(final boolean uniquevalue) {
-        this.uniqueConstraint = getBooleanAsInteger(uniquevalue);
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return isBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public void setReadonly(final boolean readonly) {
-        this.readonly = getBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public Validator getValidator() {
-        if (validator != null) {
-            return validator;
-        }
-
-        if (getValidatorClass() != null && getValidatorClass().length() > 0) {
-            try {
-                Constructor<?> validatorConstructor = Class.forName(getValidatorClass()).
-                        getConstructor(new Class<?>[] { PlainSchema.class });
-                validator = (Validator) validatorConstructor.newInstance(this);
-            } catch (Exception e) {
-                LOG.error("Could not instantiate validator of type {}, reverting to {}",
-                        getValidatorClass(), BasicValidator.class.getSimpleName(), e);
-            }
-        }
-
-        if (validator == null) {
-            validator = new BasicValidator(this);
-        }
-
-        return validator;
-    }
-
-    @Override
-    public String getValidatorClass() {
-        return validatorClass;
-    }
-
-    @Override
-    public void setValidatorClass(final String validatorClass) {
-        this.validatorClass = validatorClass;
-    }
-
-    @Override
-    public String getEnumerationValues() {
-        return enumerationValues;
-    }
-
-    @Override
-    public void setEnumerationValues(final String enumerationValues) {
-        this.enumerationValues = enumerationValues;
-    }
-
-    @Override
-    public String getEnumerationKeys() {
-        return enumerationKeys;
-    }
-
-    @Override
-    public void setEnumerationKeys(final String enumerationKeys) {
-        this.enumerationKeys = enumerationKeys;
-    }
-
-    @Override
-    public String getConversionPattern() {
-        if (!getType().isConversionPatternNeeded()) {
-            LOG.debug("Conversion pattern is not needed: {}'s type is {}", this, getType());
-        }
-
-        return conversionPattern;
-    }
-
-    @Override
-    public void setConversionPattern(final String conversionPattern) {
-        if (StringUtils.isNotBlank(conversionPattern) && !getType().isConversionPatternNeeded()) {
-            LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType());
-        }
-
-        this.conversionPattern = conversionPattern;
-    }
-
-    @Override
-    public String getSecretKey() {
-        return secretKey;
-    }
-
-    @Override
-    public void setSecretKey(final String secretKey) {
-        this.secretKey = secretKey;
-    }
-
-    @Override
-    public CipherAlgorithm getCipherAlgorithm() {
-        return cipherAlgorithm;
-    }
-
-    @Override
-    public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) {
-        this.cipherAlgorithm = cipherAlgorithm;
-    }
-
-    @Override
-    public String getMimeType() {
-        return mimeType;
-    }
-
-    @Override
-    public void setMimeType(final String mimeType) {
-        this.mimeType = mimeType;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
deleted file mode 100644
index 166309f..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
+++ /dev/null
@@ -1,85 +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;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-import javax.persistence.MappedSuperclass;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-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.Realm;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-@MappedSuperclass
-public abstract class AbstractSubject<P extends PlainAttr, D extends DerAttr, V extends VirAttr>
-        extends AbstractAttributable<P, D, V> implements Subject<P, D, V> {
-
-    private static final long serialVersionUID = -6876467491398928855L;
-
-    @ManyToOne(fetch = FetchType.EAGER, optional = false)
-    protected JPARealm realm;
-
-    @Override
-    public Realm getRealm() {
-        return realm;
-    }
-
-    @Override
-    public void setRealm(final Realm realm) {
-        checkType(realm, JPARealm.class);
-        this.realm = (JPARealm) realm;
-    }
-
-    protected abstract Set<JPAExternalResource> internalGetResources();
-
-    @Override
-    public boolean addResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return internalGetResources().add((JPAExternalResource) resource);
-    }
-
-    @Override
-    public boolean removeResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return internalGetResources().remove((JPAExternalResource) resource);
-    }
-
-    @Override
-    public Set<? extends ExternalResource> getResources() {
-        return internalGetResources();
-    }
-
-    @Override
-    public Set<String> getResourceNames() {
-        return CollectionUtils.collect(getResources(), new Transformer<ExternalResource, String>() {
-
-            @Override
-            public String transform(final ExternalResource input) {
-                return input.getKey();
-            }
-        }, new HashSet<String>());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
index 7097c8d..1ed64f3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
@@ -20,16 +20,20 @@ package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.ArrayList;
 import java.util.List;
-
+import javax.persistence.Column;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import javax.persistence.Transient;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
 @MappedSuperclass
-public abstract class AbstractVirAttr extends AbstractEntity<Long> implements VirAttr {
+public abstract class AbstractVirAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements VirAttr<O> {
 
     private static final long serialVersionUID = 5023204776925954907L;
 
@@ -40,6 +44,10 @@ public abstract class AbstractVirAttr extends AbstractEntity<Long> implements Vi
     @Transient
     protected List<String> values = new ArrayList<>();
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPAVirSchema schema;
+
     @Override
     public Long getKey() {
         return id;
@@ -51,12 +59,23 @@ public abstract class AbstractVirAttr extends AbstractEntity<Long> implements Vi
     }
 
     @Override
-    public boolean addValue(final String value) {
+    public boolean add(final String value) {
         return !values.contains(value) && values.add(value);
     }
 
     @Override
-    public boolean removeValue(final String value) {
+    public boolean remove(final String value) {
         return values.remove(value);
     }
+
+    @Override
+    public VirSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final VirSchema virSchema) {
+        checkType(virSchema, JPAVirSchema.class);
+        this.schema = (JPAVirSchema) virSchema;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
deleted file mode 100644
index 94b34dc..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
+++ /dev/null
@@ -1,41 +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;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-
-@MappedSuperclass
-public abstract class AbstractVirAttrTemplate<V extends VirSchema> extends AbstractAttrTemplate<V> {
-
-    private static final long serialVersionUID = -943169893494860655L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
deleted file mode 100644
index 9541a2e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
+++ /dev/null
@@ -1,89 +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;
-
-import javax.persistence.Basic;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@SchemaNameCheck
-public abstract class AbstractVirSchema extends AbstractEntity<String> implements VirSchema {
-
-    private static final long serialVersionUID = 3274006935328590141L;
-
-    @Id
-    private String name;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer readonly;
-
-    public AbstractVirSchema() {
-        super();
-
-        readonly = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.name = key;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return AttrSchemaType.String;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return Boolean.FALSE.toString().toLowerCase();
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return Boolean.TRUE;
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return Boolean.FALSE;
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return isBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public void setReadonly(final boolean readonly) {
-        this.readonly = getBooleanAsInteger(readonly);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
index 9509e38..6949817 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
@@ -26,12 +26,12 @@ import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
-import javax.validation.Valid;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @Entity
 @DiscriminatorValue("AccountPolicy")
@@ -44,10 +44,9 @@ public class JPAAccountPolicy extends JPAPolicy implements AccountPolicy {
      */
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(joinColumns =
-            @JoinColumn(name = "account_policy_id"),
+            @JoinColumn(name = "accountPolicy_id"),
             inverseJoinColumns =
             @JoinColumn(name = "resource_name"))
-    @Valid
     private Set<JPAExternalResource> resources = new HashSet<>();
 
     public JPAAccountPolicy() {


[08/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
new file mode 100644
index 0000000..3551a80
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -0,0 +1,663 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
+import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.provisioning.java.VirAttrHandler;
+import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+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.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+abstract class AbstractAnyDataBinder {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class);
+
+    @Autowired
+    protected RealmDAO realmDAO;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @Autowired
+    protected PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    protected DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    protected VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    protected PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    protected DerAttrDAO derAttrDAO;
+
+    @Autowired
+    protected VirAttrDAO virAttrDAO;
+
+    @Autowired
+    protected PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    protected ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    protected PolicyDAO policyDAO;
+
+    @Autowired
+    protected EntityFactory entityFactory;
+
+    @Autowired
+    protected AnyUtilsFactory anyUtilsFactory;
+
+    @Autowired
+    protected VirAttrHandler virtAttrHander;
+
+    protected void setRealm(final Any<?, ?, ?> any, final AnyMod anyMod) {
+        if (StringUtils.isNotBlank(anyMod.getRealm())) {
+            Realm newRealm = realmDAO.find(anyMod.getRealm());
+            if (newRealm == null) {
+                LOG.warn("Invalid realm specified: {}, ignoring", anyMod.getRealm());
+            } else {
+                any.setRealm(newRealm);
+            }
+        }
+    }
+
+    protected PlainSchema getPlainSchema(final String schemaName) {
+        PlainSchema schema = null;
+        if (StringUtils.isNotBlank(schemaName)) {
+            schema = plainSchemaDAO.find(schemaName);
+
+            // safely ignore invalid schemas from AttrTO
+            if (schema == null) {
+                LOG.debug("Ignoring invalid schema {}", schemaName);
+            } else if (schema.isReadonly()) {
+                schema = null;
+
+                LOG.debug("Ignoring readonly schema {}", schemaName);
+            }
+        }
+
+        return schema;
+    }
+
+    private DerSchema getDerSchema(final String derSchemaName) {
+        DerSchema schema = null;
+        if (StringUtils.isNotBlank(derSchemaName)) {
+            schema = derSchemaDAO.find(derSchemaName);
+            if (schema == null) {
+                LOG.debug("Ignoring invalid derived schema {}", derSchemaName);
+            }
+        }
+
+        return schema;
+    }
+
+    protected void fillAttribute(final List<String> values, final AnyUtils anyUtils,
+            final PlainSchema schema, final PlainAttr<?> attr, final SyncopeClientException invalidValues) {
+
+        // if schema is multivalue, all values are considered for addition;
+        // otherwise only the fist one - if provided - is considered
+        List<String> valuesProvided = schema.isMultivalue()
+                ? values
+                : (values.isEmpty()
+                        ? Collections.<String>emptyList()
+                        : Collections.singletonList(values.iterator().next()));
+
+        for (String value : valuesProvided) {
+            if (value == null || value.isEmpty()) {
+                LOG.debug("Null value for {}, ignoring", schema.getKey());
+            } else {
+                try {
+                    attr.add(value, anyUtils);
+                } catch (InvalidPlainAttrValueException e) {
+                    LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e);
+
+                    invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    private boolean evaluateMandatoryCondition(final AnyUtils anyUtils, final ExternalResource resource,
+            final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) {
+
+        boolean result = false;
+
+        Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems(
+                anyUtils.getMappingItems(resource.getProvision(any.getType()), MappingPurpose.PROPAGATION),
+                intAttrName, intMappingType);
+        for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) {
+            MappingItem mapping = itor.next();
+            result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), any);
+        }
+
+        return result;
+    }
+
+    private boolean evaluateMandatoryCondition(final AnyUtils anyUtils,
+            final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) {
+
+        boolean result = false;
+
+        Iterable<? extends ExternalResource> iterable = any instanceof User
+                ? userDAO.findAllResources((User) any)
+                : any instanceof Group
+                        ? ((Group) any).getResources()
+                        : Collections.<ExternalResource>emptySet();
+
+        for (Iterator<? extends ExternalResource> itor = iterable.iterator(); itor.hasNext() && !result;) {
+            ExternalResource resource = itor.next();
+            if (resource.isEnforceMandatoryCondition()) {
+                result |= evaluateMandatoryCondition(
+                        anyUtils, resource, any, intAttrName, intMappingType);
+            }
+        }
+
+        return result;
+    }
+
+    private SyncopeClientException checkMandatory(final AnyUtils anyUtils, final Any<?, ?, ?> any) {
+        SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
+
+        // Check if there is some mandatory schema defined for which no value has been provided
+        List<PlainSchema> plainSchemas = plainSchemaDAO.findAll();
+        for (PlainSchema schema : plainSchemas) {
+            if (any.getPlainAttr(schema.getKey()) == null
+                    && !schema.isReadonly()
+                    && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any)
+                    || evaluateMandatoryCondition(anyUtils, any, schema.getKey(),
+                            anyUtils.plainIntMappingType()))) {
+
+                LOG.error("Mandatory schema " + schema.getKey() + " not provided with values");
+
+                reqValMissing.getElements().add(schema.getKey());
+            }
+        }
+
+        List<DerSchema> derSchemas = derSchemaDAO.findAll();
+        for (DerSchema derSchema : derSchemas) {
+            if (any.getDerAttr(derSchema.getKey()) == null
+                    && evaluateMandatoryCondition(anyUtils, any, derSchema.getKey(),
+                            anyUtils.derIntMappingType())) {
+
+                LOG.error("Mandatory derived schema " + derSchema.getKey() + " does not evaluate to any value");
+
+                reqValMissing.getElements().add(derSchema.getKey());
+            }
+        }
+
+        List<VirSchema> virSchemas = virSchemaDAO.findAll();
+        for (VirSchema virSchema : virSchemas) {
+            if (any.getVirAttr(virSchema.getKey()) == null
+                    && !virSchema.isReadonly()
+                    && evaluateMandatoryCondition(anyUtils, any, virSchema.getKey(),
+                            anyUtils.virIntMappingType())) {
+
+                LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values");
+
+                reqValMissing.getElements().add(virSchema.getKey());
+            }
+        }
+
+        return reqValMissing;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    protected PropagationByResource fill(final Any any, final AnyMod anyMod, final AnyUtils anyUtils,
+            final SyncopeClientCompositeException scce) {
+
+        PropagationByResource propByRes = new PropagationByResource();
+
+        SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
+
+        // 1. resources to be removed
+        for (String resourceToBeRemoved : anyMod.getResourcesToRemove()) {
+            ExternalResource resource = resourceDAO.find(resourceToBeRemoved);
+            if (resource != null) {
+                propByRes.add(ResourceOperation.DELETE, resource.getKey());
+                ((Any<?, ?, ?>) any).remove(resource);
+            }
+        }
+
+        LOG.debug("Resources to be removed:\n{}", propByRes);
+
+        // 2. resources to be added
+        for (String resourceToBeAdded : anyMod.getResourcesToAdd()) {
+            ExternalResource resource = resourceDAO.find(resourceToBeAdded);
+            if (resource != null) {
+                propByRes.add(ResourceOperation.CREATE, resource.getKey());
+                ((Any<?, ?, ?>) any).add(resource);
+            }
+        }
+
+        LOG.debug("Resources to be added:\n{}", propByRes);
+
+        Set<ExternalResource> externalResources = new HashSet<>();
+        if (any instanceof User) {
+            externalResources.addAll(userDAO.findAllResources((User) any));
+        } else if (any instanceof Group) {
+            externalResources.addAll(((Group) any).getResources());
+        } else if (any instanceof AnyObject) {
+            externalResources.addAll(anyObjectDAO.findAllResources((AnyObject) any));
+        }
+
+        // 3. attributes to be removed
+        for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) {
+            PlainSchema schema = getPlainSchema(attributeToBeRemoved);
+            if (schema != null) {
+                PlainAttr<?> attr = any.getPlainAttr(schema.getKey());
+                if (attr == null) {
+                    LOG.debug("No attribute found for schema {}", schema);
+                } else {
+                    String newValue = null;
+                    for (AttrMod mod : anyMod.getPlainAttrsToUpdate()) {
+                        if (schema.getKey().equals(mod.getSchema())) {
+                            newValue = mod.getValuesToBeAdded().get(0);
+                        }
+                    }
+
+                    if (!schema.isUniqueConstraint()
+                            || (!attr.getUniqueValue().getStringValue().equals(newValue))) {
+
+                        any.remove(attr);
+                        plainAttrDAO.delete(attr.getKey(), anyUtils.plainAttrClass());
+                    }
+                }
+
+                for (ExternalResource resource : externalResources) {
+                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                            resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
+
+                        if (schema.getKey().equals(mapItem.getIntAttrName())
+                                && mapItem.getIntMappingType() == anyUtils.plainIntMappingType()) {
+
+                            propByRes.add(ResourceOperation.UPDATE, resource.getKey());
+
+                            if (mapItem.isConnObjectKey() && attr != null && !attr.getValuesAsStrings().isEmpty()) {
+                                propByRes.addOldAccountId(resource.getKey(), attr.getValuesAsStrings().get(0));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        LOG.debug("Attributes to be removed:\n{}", propByRes);
+
+        // 4. attributes to be updated
+        for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) {
+            PlainSchema schema = getPlainSchema(attributeMod.getSchema());
+            PlainAttr attr = null;
+            if (schema != null) {
+                attr = any.getPlainAttr(schema.getKey());
+                if (attr == null) {
+                    attr = anyUtils.newPlainAttr();
+                    attr.setSchema(schema);
+                    if (attr.getSchema() == null) {
+                        LOG.debug("Ignoring {} because no valid schema or template was found", attributeMod);
+                    } else {
+                        attr.setOwner(any);
+                        any.add(attr);
+                    }
+                }
+            }
+
+            if (schema != null && attr != null && attr.getSchema() != null) {
+                virtAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, schema.getKey(),
+                        externalResources, anyUtils.plainIntMappingType(), propByRes);
+
+                // 1.1 remove values
+                Set<Long> valuesToBeRemoved = new HashSet<>();
+                for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) {
+                    if (attr.getSchema().isUniqueConstraint()) {
+                        if (attr.getUniqueValue() != null
+                                && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) {
+
+                            valuesToBeRemoved.add(attr.getUniqueValue().getKey());
+                        }
+                    } else {
+                        for (PlainAttrValue mav : ((PlainAttr<?>) attr).getValues()) {
+                            if (valueToBeRemoved.equals(mav.getValueAsString())) {
+                                valuesToBeRemoved.add(mav.getKey());
+                            }
+                        }
+                    }
+                }
+                for (Long attributeValueId : valuesToBeRemoved) {
+                    plainAttrValueDAO.delete(attributeValueId, anyUtils.plainAttrValueClass());
+                }
+
+                // 1.2 add values
+                List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded();
+                if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty()
+                        && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
+                        || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
+
+                    fillAttribute(attributeMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
+                }
+
+                // if no values are in, the attribute can be safely removed
+                if (attr.getValuesAsStrings().isEmpty()) {
+                    plainAttrDAO.delete(attr);
+                }
+            }
+        }
+
+        if (!invalidValues.isEmpty()) {
+            scce.addException(invalidValues);
+        }
+
+        LOG.debug("Attributes to be updated:\n{}", propByRes);
+
+        // 5. derived attributes to be removed
+        for (String derAttrToBeRemoved : anyMod.getDerAttrsToRemove()) {
+            DerSchema derSchema = getDerSchema(derAttrToBeRemoved);
+            if (derSchema != null) {
+                DerAttr derAttr = any.getDerAttr(derSchema.getKey());
+                if (derAttr == null) {
+                    LOG.debug("No derived attribute found for schema {}", derSchema.getKey());
+                } else {
+                    derAttrDAO.delete(derAttr);
+                }
+
+                for (ExternalResource resource : externalResources) {
+                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                            resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
+
+                        if (derSchema.getKey().equals(mapItem.getIntAttrName())
+                                && mapItem.getIntMappingType() == anyUtils.derIntMappingType()) {
+
+                            propByRes.add(ResourceOperation.UPDATE, resource.getKey());
+
+                            if (mapItem.isConnObjectKey() && derAttr != null
+                                    && !derAttr.getValue(any.getPlainAttrs()).isEmpty()) {
+
+                                propByRes.addOldAccountId(resource.getKey(),
+                                        derAttr.getValue(any.getPlainAttrs()));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        LOG.debug("Derived attributes to be removed:\n{}", propByRes);
+
+        // 6. derived attributes to be added
+        for (String derAttrToBeAdded : anyMod.getDerAttrsToAdd()) {
+            DerSchema derSchema = getDerSchema(derAttrToBeAdded);
+            if (derSchema != null) {
+                virtAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, derSchema.getKey(),
+                        externalResources, anyUtils.derIntMappingType(), propByRes);
+
+                DerAttr derAttr = anyUtils.newDerAttr();
+                derAttr.setSchema(derSchema);
+                if (derAttr.getSchema() == null) {
+                    LOG.debug("Ignoring {} because no valid schema or template was found", derAttrToBeAdded);
+                } else {
+                    derAttr.setOwner(any);
+                    any.add(derAttr);
+                }
+            }
+        }
+
+        LOG.debug("Derived attributes to be added:\n{}", propByRes);
+
+        // Finally, check if mandatory values are missing
+        SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any);
+        if (!requiredValuesMissing.isEmpty()) {
+            scce.addException(requiredValuesMissing);
+        }
+
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
+
+        return propByRes;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    protected void fill(final Any any, final AnyTO anyTO,
+            final AnyUtils anyUtils, final SyncopeClientCompositeException scce) {
+
+        // 1. attributes
+        SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
+
+        // Only consider attributeTO with values
+        for (AttrTO attributeTO : anyTO.getPlainAttrs()) {
+            if (attributeTO.getValues() != null && !attributeTO.getValues().isEmpty()) {
+                PlainSchema schema = getPlainSchema(attributeTO.getSchema());
+
+                if (schema != null) {
+                    PlainAttr attr = any.getPlainAttr(schema.getKey());
+                    if (attr == null) {
+                        attr = anyUtils.newPlainAttr();
+                        attr.setSchema(schema);
+                    }
+                    if (attr.getSchema() == null) {
+                        LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
+                    } else {
+                        fillAttribute(attributeTO.getValues(), anyUtils, schema, attr, invalidValues);
+
+                        if (!attr.getValuesAsStrings().isEmpty()) {
+                            any.add(attr);
+                            attr.setOwner(any);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!invalidValues.isEmpty()) {
+            scce.addException(invalidValues);
+        }
+
+        // 2. derived attributes
+        for (AttrTO attributeTO : anyTO.getDerAttrs()) {
+            DerSchema derSchema = getDerSchema(attributeTO.getSchema());
+
+            if (derSchema != null) {
+                DerAttr derAttr = anyUtils.newDerAttr();
+                derAttr.setSchema(derSchema);
+                if (derAttr.getSchema() == null) {
+                    LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
+                } else {
+                    derAttr.setOwner(any);
+                    any.add(derAttr);
+                }
+            }
+        }
+
+        // 3. virtual attributes
+        for (AttrTO vattrTO : anyTO.getVirAttrs()) {
+            VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema());
+
+            if (virSchema != null) {
+                VirAttr virAttr = anyUtils.newVirAttr();
+                virAttr.setSchema(virSchema);
+                if (virAttr.getSchema() == null) {
+                    LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO);
+                } else {
+                    virAttr.setOwner(any);
+                    any.add(virAttr);
+                }
+            }
+        }
+
+        virtAttrHander.fillVirtual(any, anyTO.getVirAttrs(), anyUtils);
+
+        // 4. realm & resources
+        Realm realm = realmDAO.find(anyTO.getRealm());
+        if (realm == null) {
+            SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            noRealm.getElements().add(
+                    "Invalid or null realm specified: " + anyTO.getRealm());
+            scce.addException(noRealm);
+        }
+        ((Any<?, ?, ?>) any).setRealm(realm);
+
+        for (String resourceName : anyTO.getResources()) {
+            ExternalResource resource = resourceDAO.find(resourceName);
+
+            if (resource != null) {
+                ((Any<?, ?, ?>) any).add(resource);
+            }
+        }
+
+        SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any);
+        if (!requiredValuesMissing.isEmpty()) {
+            scce.addException(requiredValuesMissing);
+        }
+
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
+    }
+
+    protected void fillTO(final AnyTO anyTO,
+            final String realmFullPath,
+            final Collection<? extends PlainAttr<?>> attrs,
+            final Collection<? extends DerAttr<?>> derAttrs,
+            final Collection<? extends VirAttr<?>> virAttrs,
+            final Collection<? extends ExternalResource> resources) {
+
+        AttrTO attributeTO;
+        for (PlainAttr<?> attr : attrs) {
+            attributeTO = new AttrTO();
+            attributeTO.setSchema(attr.getSchema().getKey());
+            attributeTO.getValues().addAll(attr.getValuesAsStrings());
+            attributeTO.setReadonly(attr.getSchema().isReadonly());
+
+            anyTO.getPlainAttrs().add(attributeTO);
+        }
+
+        for (DerAttr<?> derAttr : derAttrs) {
+            attributeTO = new AttrTO();
+            attributeTO.setSchema(derAttr.getSchema().getKey());
+            attributeTO.getValues().add(derAttr.getValue(attrs));
+            attributeTO.setReadonly(true);
+
+            anyTO.getDerAttrs().add(attributeTO);
+        }
+
+        for (VirAttr<?> virAttr : virAttrs) {
+            attributeTO = new AttrTO();
+            attributeTO.setSchema(virAttr.getSchema().getKey());
+            attributeTO.getValues().addAll(virAttr.getValues());
+            attributeTO.setReadonly(virAttr.getSchema().isReadonly());
+
+            anyTO.getVirAttrs().add(attributeTO);
+        }
+
+        anyTO.setRealm(realmFullPath);
+        for (ExternalResource resource : resources) {
+            anyTO.getResources().add(resource.getKey());
+        }
+    }
+
+    protected Map<String, String> getConnObjectKeys(final Any<?, ?, ?> any) {
+        Map<String, String> connObjectKeys = new HashMap<>();
+
+        Iterable<? extends ExternalResource> iterable = any instanceof User
+                ? userDAO.findAllResources((User) any)
+                : any instanceof AnyObject
+                        ? anyObjectDAO.findAllResources((AnyObject) any)
+                        : ((Group) any).getResources();
+        for (ExternalResource resource : iterable) {
+            Provision provision = resource.getProvision(any.getType());
+            if (provision.getMapping() != null) {
+                MappingItem connObjectKeyItem = anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision);
+                if (connObjectKeyItem == null) {
+                    throw new NotFoundException(
+                            "ConnObjectKey mapping for " + any.getType().getKey() + " " + any.getKey()
+                            + " on resource '" + resource.getKey() + "'");
+                }
+
+                connObjectKeys.put(resource.getKey(), MappingUtils.getConnObjectKeyValue(any, provision));
+            }
+        }
+
+        return connObjectKeys;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
deleted file mode 100644
index b94ffa2..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.data;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeClientCompositeException;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
-import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.provisioning.java.VirAttrHandler;
-import org.apache.syncope.core.misc.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-abstract class AbstractAttributableDataBinder {
-
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractAttributableDataBinder.class);
-
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    @Autowired
-    protected PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    protected DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    protected VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    protected PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    protected DerAttrDAO derAttrDAO;
-
-    @Autowired
-    protected VirAttrDAO virAttrDAO;
-
-    @Autowired
-    protected PlainAttrValueDAO plainAttrValueDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    protected MembershipDAO membershipDAO;
-
-    @Autowired
-    protected PolicyDAO policyDAO;
-
-    @Autowired
-    protected EntityFactory entityFactory;
-
-    @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
-
-    @Autowired
-    protected VirAttrHandler virtAttrHander;
-
-    protected void setRealm(final Subject<?, ?, ?> subject, final AbstractSubjectMod subjectMod) {
-        if (StringUtils.isNotBlank(subjectMod.getRealm())) {
-            Realm newRealm = realmDAO.find(subjectMod.getRealm());
-            if (newRealm == null) {
-                LOG.warn("Invalid realm specified: {}, ignoring", subjectMod.getRealm());
-            } else {
-                subject.setRealm(newRealm);
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <T extends Schema> T getSchema(final String schemaName, final Class<T> reference) {
-        T result = null;
-
-        if (PlainSchema.class.isAssignableFrom(reference)) {
-            result = (T) getPlainSchema(schemaName, (Class<? extends PlainSchema>) reference);
-        } else if (DerSchema.class.isAssignableFrom(reference)) {
-            result = (T) getDerSchema(schemaName, (Class<? extends DerSchema>) reference);
-        } else if (VirSchema.class.isAssignableFrom(reference)) {
-            result = (T) virtAttrHander.getVirSchema(schemaName, (Class<? extends VirSchema>) reference);
-        }
-
-        return result;
-    }
-
-    protected <T extends PlainSchema> T getPlainSchema(final String schemaName, final Class<T> reference) {
-        T schema = null;
-        if (StringUtils.isNotBlank(schemaName)) {
-            schema = plainSchemaDAO.find(schemaName, reference);
-
-            // safely ignore invalid schemas from AttrTO
-            if (schema == null) {
-                LOG.debug("Ignoring invalid schema {}", schemaName);
-            } else if (schema.isReadonly()) {
-                schema = null;
-
-                LOG.debug("Ignoring readonly schema {}", schemaName);
-            }
-        }
-
-        return schema;
-    }
-
-    private <T extends DerSchema> T getDerSchema(final String derSchemaName, final Class<T> reference) {
-        T derivedSchema = null;
-        if (StringUtils.isNotBlank(derSchemaName)) {
-            derivedSchema = derSchemaDAO.find(derSchemaName, reference);
-            if (derivedSchema == null) {
-                LOG.debug("Ignoring invalid derived schema {}", derSchemaName);
-            }
-        }
-
-        return derivedSchema;
-    }
-
-    protected void fillAttribute(final List<String> values, final AttributableUtils attributableUtil,
-            final PlainSchema schema, final PlainAttr attr, final SyncopeClientException invalidValues) {
-
-        // if schema is multivalue, all values are considered for addition;
-        // otherwise only the fist one - if provided - is considered
-        List<String> valuesProvided = schema.isMultivalue()
-                ? values
-                : (values.isEmpty()
-                        ? Collections.<String>emptyList()
-                        : Collections.singletonList(values.iterator().next()));
-
-        for (String value : valuesProvided) {
-            if (value == null || value.isEmpty()) {
-                LOG.debug("Null value for {}, ignoring", schema.getKey());
-            } else {
-                try {
-                    attr.addValue(value, attributableUtil);
-                } catch (InvalidPlainAttrValueException e) {
-                    LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e);
-
-                    invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage());
-                }
-            }
-        }
-    }
-
-    private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils, final ExternalResource resource,
-            final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) {
-
-        boolean result = false;
-
-        Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems(
-                attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION), intAttrName, intMappingType);
-        for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) {
-            MappingItem mapping = itor.next();
-            result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), attributable);
-        }
-
-        return result;
-    }
-
-    private boolean evaluateMandatoryCondition(final AttributableUtils attrUtils,
-            final Attributable<?, ?, ?> attributable, final String intAttrName, final IntMappingType intMappingType) {
-
-        boolean result = false;
-
-        Iterable<? extends ExternalResource> iterable = attributable instanceof User
-                ? userDAO.findAllResources((User) attributable)
-                : attributable instanceof Group
-                        ? ((Group) attributable).getResources()
-                        : Collections.<ExternalResource>emptySet();
-
-        for (Iterator<? extends ExternalResource> itor = iterable.iterator(); itor.hasNext() && !result;) {
-            ExternalResource resource = itor.next();
-            if (resource.isEnforceMandatoryCondition()) {
-                result |= evaluateMandatoryCondition(
-                        attrUtils, resource, attributable, intAttrName, intMappingType);
-            }
-        }
-
-        return result;
-    }
-
-    private SyncopeClientException checkMandatory(final AttributableUtils attrUtils,
-            final Attributable<?, ?, ?> attributable) {
-
-        SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
-
-        // Check if there is some mandatory schema defined for which no value has been provided
-        List<? extends PlainSchema> plainSchemas;
-        switch (attrUtils.getType()) {
-            case GROUP:
-                plainSchemas = ((Group) attributable).getAttrTemplateSchemas(GPlainAttrTemplate.class);
-                break;
-
-            case MEMBERSHIP:
-                plainSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MPlainAttrTemplate.class);
-                break;
-
-            case USER:
-            default:
-                plainSchemas = plainSchemaDAO.findAll(attrUtils.plainSchemaClass());
-        }
-        for (PlainSchema schema : plainSchemas) {
-            if (attributable.getPlainAttr(schema.getKey()) == null
-                    && !schema.isReadonly()
-                    && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), attributable)
-                    || evaluateMandatoryCondition(attrUtils, attributable, schema.getKey(),
-                            attrUtils.plainIntMappingType()))) {
-
-                LOG.error("Mandatory schema " + schema.getKey() + " not provided with values");
-
-                reqValMissing.getElements().add(schema.getKey());
-            }
-        }
-
-        List<? extends DerSchema> derSchemas;
-        switch (attrUtils.getType()) {
-            case GROUP:
-                derSchemas = ((Group) attributable).getAttrTemplateSchemas(GDerAttrTemplate.class);
-                break;
-
-            case MEMBERSHIP:
-                derSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MDerAttrTemplate.class);
-                break;
-
-            case USER:
-            default:
-                derSchemas = derSchemaDAO.findAll(attrUtils.derSchemaClass());
-        }
-        for (DerSchema derSchema : derSchemas) {
-            if (attributable.getDerAttr(derSchema.getKey()) == null
-                    && evaluateMandatoryCondition(attrUtils, attributable, derSchema.getKey(),
-                            attrUtils.derIntMappingType())) {
-
-                LOG.error("Mandatory derived schema " + derSchema.getKey() + " does not evaluate to any value");
-
-                reqValMissing.getElements().add(derSchema.getKey());
-            }
-        }
-
-        List<? extends VirSchema> virSchemas;
-        switch (attrUtils.getType()) {
-            case GROUP:
-                virSchemas = ((Group) attributable).getAttrTemplateSchemas(GVirAttrTemplate.class);
-                break;
-
-            case MEMBERSHIP:
-                virSchemas = ((Membership) attributable).getGroup().getAttrTemplateSchemas(MVirAttrTemplate.class);
-                break;
-
-            case USER:
-            default:
-                virSchemas = virSchemaDAO.findAll(attrUtils.virSchemaClass());
-        }
-        for (VirSchema virSchema : virSchemas) {
-            if (attributable.getVirAttr(virSchema.getKey()) == null
-                    && !virSchema.isReadonly()
-                    && evaluateMandatoryCondition(attrUtils, attributable, virSchema.getKey(),
-                            attrUtils.virIntMappingType())) {
-
-                LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values");
-
-                reqValMissing.getElements().add(virSchema.getKey());
-            }
-        }
-
-        return reqValMissing;
-    }
-
-    private void setPlainAttrSchema(final Attributable<?, ?, ?> attributable,
-            final PlainAttr attr, final PlainSchema schema) {
-
-        if (attr instanceof UPlainAttr) {
-            ((UPlainAttr) attr).setSchema((UPlainSchema) schema);
-        } else if (attr instanceof GPlainAttr) {
-            GPlainAttrTemplate template =
-                    ((Group) attributable).getAttrTemplate(GPlainAttrTemplate.class, schema.getKey());
-            if (template != null) {
-                ((GPlainAttr) attr).setTemplate(template);
-            }
-        } else if (attr instanceof MPlainAttr) {
-            MPlainAttrTemplate template = ((Membership) attributable).getGroup().
-                    getAttrTemplate(MPlainAttrTemplate.class, schema.getKey());
-            if (template != null) {
-                ((MPlainAttr) attr).setTemplate(template);
-            }
-        }
-    }
-
-    private void setDerAttrSchema(final Attributable<?, ?, ?> attributable,
-            final DerAttr derAttr, final DerSchema derSchema) {
-
-        if (derAttr instanceof UDerAttr) {
-            ((UDerAttr) derAttr).setSchema((UDerSchema) derSchema);
-        } else if (derAttr instanceof GDerAttr) {
-            GDerAttrTemplate template = ((Group) attributable).
-                    getAttrTemplate(GDerAttrTemplate.class, derSchema.getKey());
-            if (template != null) {
-                ((GDerAttr) derAttr).setTemplate(template);
-            }
-        } else if (derAttr instanceof MDerAttr) {
-            MDerAttrTemplate template = ((Membership) attributable).getGroup().
-                    getAttrTemplate(MDerAttrTemplate.class, derSchema.getKey());
-            if (template != null) {
-                ((MDerAttr) derAttr).setTemplate(template);
-            }
-        }
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected PropagationByResource fill(final Attributable attributable,
-            final AbstractAttributableMod attributableMod, final AttributableUtils attrUtils,
-            final SyncopeClientCompositeException scce) {
-
-        PropagationByResource propByRes = new PropagationByResource();
-
-        SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
-
-        if (attributable instanceof Subject && attributableMod instanceof AbstractSubjectMod) {
-            // 1. resources to be removed
-            for (String resourceToBeRemoved : ((AbstractSubjectMod) attributableMod).getResourcesToRemove()) {
-                ExternalResource resource = resourceDAO.find(resourceToBeRemoved);
-                if (resource != null) {
-                    propByRes.add(ResourceOperation.DELETE, resource.getKey());
-                    ((Subject<?, ?, ?>) attributable).removeResource(resource);
-                }
-            }
-
-            LOG.debug("Resources to be removed:\n{}", propByRes);
-
-            // 2. resources to be added
-            for (String resourceToBeAdded : ((AbstractSubjectMod) attributableMod).getResourcesToAdd()) {
-                ExternalResource resource = resourceDAO.find(resourceToBeAdded);
-                if (resource != null) {
-                    propByRes.add(ResourceOperation.CREATE, resource.getKey());
-                    ((Subject<?, ?, ?>) attributable).addResource(resource);
-                }
-            }
-
-            LOG.debug("Resources to be added:\n{}", propByRes);
-        }
-
-        Set<ExternalResource> externalResources = new HashSet<>();
-        if (attributable instanceof User) {
-            externalResources.addAll(userDAO.findAllResources((User) attributable));
-        } else if (attributable instanceof Group) {
-            externalResources.addAll(((Group) attributable).getResources());
-        } else if (attributable instanceof Membership) {
-            externalResources.addAll(userDAO.findAllResources(((Membership) attributable).getUser()));
-            externalResources.addAll(((Membership) attributable).getGroup().getResources());
-        }
-
-        // 3. attributes to be removed
-        for (String attributeToBeRemoved : attributableMod.getPlainAttrsToRemove()) {
-            PlainSchema schema = getPlainSchema(attributeToBeRemoved, attrUtils.plainSchemaClass());
-            if (schema != null) {
-                PlainAttr attr = attributable.getPlainAttr(schema.getKey());
-                if (attr == null) {
-                    LOG.debug("No attribute found for schema {}", schema);
-                } else {
-                    String newValue = null;
-                    for (AttrMod mod : attributableMod.getPlainAttrsToUpdate()) {
-                        if (schema.getKey().equals(mod.getSchema())) {
-                            newValue = mod.getValuesToBeAdded().get(0);
-                        }
-                    }
-
-                    if (!schema.isUniqueConstraint()
-                            || (!attr.getUniqueValue().getStringValue().equals(newValue))) {
-
-                        attributable.removePlainAttr(attr);
-                        plainAttrDAO.delete(attr.getKey(), attrUtils.plainAttrClass());
-                    }
-                }
-
-                if (attributable instanceof Subject) {
-                    for (ExternalResource resource : externalResources) {
-                        for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
-                            if (schema.getKey().equals(mapItem.getIntAttrName())
-                                    && mapItem.getIntMappingType() == attrUtils.plainIntMappingType()) {
-
-                                propByRes.add(ResourceOperation.UPDATE, resource.getKey());
-
-                                if (mapItem.isAccountid() && attr != null && !attr.getValuesAsStrings().isEmpty()) {
-                                    propByRes.addOldAccountId(resource.getKey(), attr.getValuesAsStrings().get(0));
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        LOG.debug("Attributes to be removed:\n{}", propByRes);
-
-        // 4. attributes to be updated
-        for (AttrMod attributeMod : attributableMod.getPlainAttrsToUpdate()) {
-            PlainSchema schema = getPlainSchema(attributeMod.getSchema(), attrUtils.plainSchemaClass());
-            PlainAttr attr = null;
-            if (schema != null) {
-                attr = attributable.getPlainAttr(schema.getKey());
-                if (attr == null) {
-                    attr = attrUtils.newPlainAttr();
-                    setPlainAttrSchema(attributable, attr, schema);
-                    if (attr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema or template was found", attributeMod);
-                    } else {
-                        attr.setOwner(attributable);
-                        attributable.addPlainAttr(attr);
-                    }
-                }
-            }
-
-            if (schema != null && attr != null && attr.getSchema() != null) {
-                if (attributable instanceof Subject) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(),
-                            externalResources, attrUtils.plainIntMappingType(), propByRes);
-                } else if (attributable instanceof Membership) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, schema.getKey(),
-                            externalResources, IntMappingType.MembershipPlainSchema, propByRes);
-                }
-
-                // 1.1 remove values
-                Set<Long> valuesToBeRemoved = new HashSet<>();
-                for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) {
-                    if (attr.getSchema().isUniqueConstraint()) {
-                        if (attr.getUniqueValue() != null
-                                && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) {
-
-                            valuesToBeRemoved.add(attr.getUniqueValue().getKey());
-                        }
-                    } else {
-                        for (PlainAttrValue mav : attr.getValues()) {
-                            if (valueToBeRemoved.equals(mav.getValueAsString())) {
-                                valuesToBeRemoved.add(mav.getKey());
-                            }
-                        }
-                    }
-                }
-                for (Long attributeValueId : valuesToBeRemoved) {
-                    plainAttrValueDAO.delete(attributeValueId, attrUtils.plainAttrValueClass());
-                }
-
-                // 1.2 add values
-                List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded();
-                if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty()
-                        && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
-                        || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
-
-                    fillAttribute(attributeMod.getValuesToBeAdded(), attrUtils, schema, attr, invalidValues);
-                }
-
-                // if no values are in, the attribute can be safely removed
-                if (attr.getValuesAsStrings().isEmpty()) {
-                    plainAttrDAO.delete(attr);
-                }
-            }
-        }
-
-        if (!invalidValues.isEmpty()) {
-            scce.addException(invalidValues);
-        }
-
-        LOG.debug("Attributes to be updated:\n{}", propByRes);
-
-        // 5. derived attributes to be removed
-        for (String derAttrToBeRemoved : attributableMod.getDerAttrsToRemove()) {
-            DerSchema derSchema = getDerSchema(derAttrToBeRemoved, attrUtils.derSchemaClass());
-            if (derSchema != null) {
-                DerAttr derAttr = attributable.getDerAttr(derSchema.getKey());
-                if (derAttr == null) {
-                    LOG.debug("No derived attribute found for schema {}", derSchema.getKey());
-                } else {
-                    derAttrDAO.delete(derAttr);
-                }
-
-                if (attributable instanceof Subject) {
-                    for (ExternalResource resource : externalResources) {
-                        for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
-                            if (derSchema.getKey().equals(mapItem.getIntAttrName())
-                                    && mapItem.getIntMappingType() == attrUtils.derIntMappingType()) {
-
-                                propByRes.add(ResourceOperation.UPDATE, resource.getKey());
-
-                                if (mapItem.isAccountid() && derAttr != null
-                                        && !derAttr.getValue(attributable.getPlainAttrs()).isEmpty()) {
-
-                                    propByRes.addOldAccountId(resource.getKey(),
-                                            derAttr.getValue(attributable.getPlainAttrs()));
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        LOG.debug("Derived attributes to be removed:\n{}", propByRes);
-
-        // 6. derived attributes to be added
-        for (String derAttrToBeAdded : attributableMod.getDerAttrsToAdd()) {
-            DerSchema derSchema = getDerSchema(derAttrToBeAdded, attrUtils.derSchemaClass());
-            if (derSchema != null) {
-                if (attributable instanceof Subject) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(),
-                            externalResources, attrUtils.derIntMappingType(), propByRes);
-                } else if (attributable instanceof Membership) {
-                    virtAttrHander.updateOnResourcesIfMappingMatches(attrUtils, derSchema.getKey(),
-                            externalResources, IntMappingType.MembershipDerivedSchema, propByRes);
-                }
-
-                DerAttr derAttr = attrUtils.newDerAttr();
-                setDerAttrSchema(attributable, derAttr, derSchema);
-                if (derAttr.getSchema() == null) {
-                    LOG.debug("Ignoring {} because no valid schema or template was found", derAttrToBeAdded);
-                } else {
-                    derAttr.setOwner(attributable);
-                    attributable.addDerAttr(derAttr);
-                }
-            }
-        }
-
-        LOG.debug("Derived attributes to be added:\n{}", propByRes);
-
-        // 7. virtual attributes: for users and groups this is delegated to PropagationManager
-        if (AttributableType.USER != attrUtils.getType() && AttributableType.GROUP != attrUtils.getType()) {
-            virtAttrHander.fillVirtual(attributable, attributableMod.getVirAttrsToRemove(),
-                    attributableMod.getVirAttrsToUpdate(), attrUtils);
-        }
-
-        // Finally, check if mandatory values are missing
-        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable);
-        if (!requiredValuesMissing.isEmpty()) {
-            scce.addException(requiredValuesMissing);
-        }
-
-        // Throw composite exception if there is at least one element set in the composing exceptions
-        if (scce.hasExceptions()) {
-            throw scce;
-        }
-
-        return propByRes;
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected void fill(final Attributable attributable, final AbstractAttributableTO attributableTO,
-            final AttributableUtils attrUtils, final SyncopeClientCompositeException scce) {
-
-        // 1. attributes
-        SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
-
-        // Only consider attributeTO with values
-        for (AttrTO attributeTO : attributableTO.getPlainAttrs()) {
-            if (attributeTO.getValues() != null && !attributeTO.getValues().isEmpty()) {
-                PlainSchema schema = getPlainSchema(attributeTO.getSchema(), attrUtils.plainSchemaClass());
-
-                if (schema != null) {
-                    PlainAttr attr = attributable.getPlainAttr(schema.getKey());
-                    if (attr == null) {
-                        attr = attrUtils.newPlainAttr();
-                        setPlainAttrSchema(attributable, attr, schema);
-                    }
-                    if (attr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
-                    } else {
-                        fillAttribute(attributeTO.getValues(), attrUtils, schema, attr, invalidValues);
-
-                        if (!attr.getValuesAsStrings().isEmpty()) {
-                            attributable.addPlainAttr(attr);
-                            attr.setOwner(attributable);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!invalidValues.isEmpty()) {
-            scce.addException(invalidValues);
-        }
-
-        // 2. derived attributes
-        for (AttrTO attributeTO : attributableTO.getDerAttrs()) {
-            DerSchema derSchema = getDerSchema(attributeTO.getSchema(), attrUtils.derSchemaClass());
-
-            if (derSchema != null) {
-                DerAttr derAttr = attrUtils.newDerAttr();
-                setDerAttrSchema(attributable, derAttr, derSchema);
-                if (derAttr.getSchema() == null) {
-                    LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
-                } else {
-                    derAttr.setOwner(attributable);
-                    attributable.addDerAttr(derAttr);
-                }
-            }
-        }
-
-        // 3. user and group virtual attributes will be evaluated by the propagation manager only (if needed).
-        if (AttributableType.USER == attrUtils.getType() || AttributableType.GROUP == attrUtils.getType()) {
-            for (AttrTO vattrTO : attributableTO.getVirAttrs()) {
-                VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema(), attrUtils.virSchemaClass());
-
-                if (virSchema != null) {
-                    VirAttr virAttr = attrUtils.newVirAttr();
-                    virtAttrHander.setVirAttrSchema(attributable, virAttr, virSchema);
-                    if (virAttr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema or template was found", vattrTO);
-                    } else {
-                        virAttr.setOwner(attributable);
-                        attributable.addVirAttr(virAttr);
-                    }
-                }
-            }
-        }
-
-        virtAttrHander.fillVirtual(attributable, attributableTO.getVirAttrs(), attrUtils);
-
-        // 4. realm & resources
-        if (attributable instanceof Subject && attributableTO instanceof AbstractSubjectTO) {
-            Realm realm = realmDAO.find(((AbstractSubjectTO) attributableTO).getRealm());
-            if (realm == null) {
-                SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
-                noRealm.getElements().add(
-                        "Invalid or null realm specified: " + ((AbstractSubjectTO) attributableTO).getRealm());
-                scce.addException(noRealm);
-            }
-            ((Subject<?, ?, ?>) attributable).setRealm(realm);
-
-            for (String resourceName : ((AbstractSubjectTO) attributableTO).getResources()) {
-                ExternalResource resource = resourceDAO.find(resourceName);
-
-                if (resource != null) {
-                    ((Subject<?, ?, ?>) attributable).addResource(resource);
-                }
-            }
-        }
-
-        SyncopeClientException requiredValuesMissing = checkMandatory(attrUtils, attributable);
-        if (!requiredValuesMissing.isEmpty()) {
-            scce.addException(requiredValuesMissing);
-        }
-
-        // Throw composite exception if there is at least one element set in the composing exceptions
-        if (scce.hasExceptions()) {
-            throw scce;
-        }
-    }
-
-    protected void fillTO(final AbstractAttributableTO attributableTO,
-            final String realmFullPath,
-            final Collection<? extends PlainAttr> attrs,
-            final Collection<? extends DerAttr> derAttrs,
-            final Collection<? extends VirAttr> virAttrs,
-            final Collection<? extends ExternalResource> resources) {
-
-        AttrTO attributeTO;
-        for (PlainAttr attr : attrs) {
-            attributeTO = new AttrTO();
-            attributeTO.setSchema(attr.getSchema().getKey());
-            attributeTO.getValues().addAll(attr.getValuesAsStrings());
-            attributeTO.setReadonly(attr.getSchema().isReadonly());
-
-            attributableTO.getPlainAttrs().add(attributeTO);
-        }
-
-        for (DerAttr derAttr : derAttrs) {
-            attributeTO = new AttrTO();
-            attributeTO.setSchema(derAttr.getSchema().getKey());
-            attributeTO.getValues().add(derAttr.getValue(attrs));
-            attributeTO.setReadonly(true);
-
-            attributableTO.getDerAttrs().add(attributeTO);
-        }
-
-        for (VirAttr virAttr : virAttrs) {
-            attributeTO = new AttrTO();
-            attributeTO.setSchema(virAttr.getSchema().getKey());
-            attributeTO.getValues().addAll(virAttr.getValues());
-            attributeTO.setReadonly(virAttr.getSchema().isReadonly());
-
-            attributableTO.getVirAttrs().add(attributeTO);
-        }
-
-        if (attributableTO instanceof AbstractSubjectTO) {
-            AbstractSubjectTO subjectTO = AbstractSubjectTO.class.cast(attributableTO);
-            subjectTO.setRealm(realmFullPath);
-            for (ExternalResource resource : resources) {
-                subjectTO.getResources().add(resource.getKey());
-            }
-        }
-    }
-
-    protected Map<String, String> getAccountIds(final Subject<?, ?, ?> subject, final AttributableType type) {
-        Map<String, String> accountIds = new HashMap<>();
-
-        Iterable<? extends ExternalResource> iterable = subject instanceof User
-                ? userDAO.findAllResources((User) subject)
-                : ((Group) subject).getResources();
-        for (ExternalResource resource : iterable) {
-            if ((type == AttributableType.USER && resource.getUmapping() != null)
-                    || (type == AttributableType.GROUP && resource.getGmapping() != null)) {
-
-                MappingItem accountIdItem = attrUtilsFactory.getInstance(type).getAccountIdItem(resource);
-                if (accountIdItem == null) {
-                    throw new NotFoundException(
-                            "AccountId mapping for " + type + " " + subject.getKey()
-                            + " on resource '" + resource.getKey() + "'");
-                }
-
-                accountIds.put(resource.getKey(), MappingUtils.getAccountIdValue(subject, resource, accountIdItem));
-            }
-        }
-
-        return accountIds;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 5e2dc1b..fe5668d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -18,26 +18,33 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
+
 import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder;
 import java.util.Collections;
+import java.util.List;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-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.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.conf.Conf;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.springframework.stereotype.Component;
 
 @Component
-public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder implements ConfigurationDataBinder {
+public class ConfigurationDataBinderImpl extends AbstractAnyDataBinder implements ConfigurationDataBinder {
 
     @Override
     public ConfTO getConfTO(final Conf conf) {
-        final ConfTO confTO = new ConfTO();
+        ConfTO confTO = new ConfTO();
         confTO.setKey(conf.getKey());
 
         fillTO(confTO, null, conf.getPlainAttrs(),
@@ -48,7 +55,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder
 
     @Override
     public AttrTO getAttrTO(final CPlainAttr attr) {
-        final AttrTO attributeTO = new AttrTO();
+        AttrTO attributeTO = new AttrTO();
         attributeTO.setSchema(attr.getSchema().getKey());
         attributeTO.getValues().addAll(attr.getValuesAsStrings());
         attributeTO.setReadonly(attr.getSchema().isReadonly());
@@ -56,9 +63,43 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder
         return attributeTO;
     }
 
+    private void fillAttribute(final List<String> values,
+            final PlainSchema schema, final CPlainAttr attr, final SyncopeClientException invalidValues) {
+
+        // if schema is multivalue, all values are considered for addition;
+        // otherwise only the fist one - if provided - is considered
+        List<String> valuesProvided = schema.isMultivalue()
+                ? values
+                : (values.isEmpty()
+                        ? Collections.<String>emptyList()
+                        : Collections.singletonList(values.iterator().next()));
+
+        for (String value : valuesProvided) {
+            if (value == null || value.isEmpty()) {
+                LOG.debug("Null value for {}, ignoring", schema.getKey());
+            } else {
+                try {
+                    PlainAttrValue attrValue;
+                    if (schema.isUniqueConstraint()) {
+                        attrValue = entityFactory.newEntity(CPlainAttrUniqueValue.class);
+                        ((PlainAttrUniqueValue) attrValue).setSchema(schema);
+                    } else {
+                        attrValue = entityFactory.newEntity(CPlainAttrValue.class);
+                    }
+
+                    attr.add(value, attrValue);
+                } catch (InvalidPlainAttrValueException e) {
+                    LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e);
+
+                    invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage());
+                }
+            }
+        }
+    }
+
     @Override
     public CPlainAttr getAttribute(final AttrTO attributeTO) {
-        CPlainSchema schema = getPlainSchema(attributeTO.getSchema(), CPlainSchema.class);
+        PlainSchema schema = getPlainSchema(attributeTO.getSchema());
         if (schema == null) {
             throw new NotFoundException("Conf schema " + attributeTO.getSchema());
         } else {
@@ -66,8 +107,7 @@ public class ConfigurationDataBinderImpl extends AbstractAttributableDataBinder
 
             CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class);
             attr.setSchema(schema);
-            fillAttribute(attributeTO.getValues(), attrUtilsFactory.getInstance(AttributableType.CONFIGURATION),
-                    schema, attr, invalidValues);
+            fillAttribute(attributeTO.getValues(), schema, attr, invalidValues);
 
             if (!invalidValues.isEmpty()) {
                 throw invalidValues;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index efe7771..17370e6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -18,30 +18,14 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
@@ -50,47 +34,20 @@ import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 @Component
 @Transactional(rollbackFor = { Throwable.class })
-public class GroupDataBinderImpl extends AbstractAttributableDataBinder implements GroupDataBinder {
+public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupDataBinder {
 
     @Autowired
     private ConnObjectUtils connObjectUtils;
 
-    private <T extends AttrTemplate<S>, S extends Schema> void setAttrTemplates(
-            final Group group, final List<String> schemaNames,
-            final Class<T> templateClass, final Class<S> schemaClass) {
-
-        List<T> toRemove = new ArrayList<>();
-        for (T template : group.getAttrTemplates(templateClass)) {
-            if (!schemaNames.contains(template.getSchema().getKey())) {
-                toRemove.add(template);
-            }
-        }
-        group.getAttrTemplates(templateClass).removeAll(toRemove);
-
-        for (String schemaName : schemaNames) {
-            if (group.getAttrTemplate(templateClass, schemaName) == null) {
-                S schema = getSchema(schemaName, schemaClass);
-                if (schema != null) {
-                    try {
-                        T template = entityFactory.newEntity(templateClass);
-                        template.setSchema(schema);
-                        template.setOwner(group);
-                        group.getAttrTemplates(templateClass).add(template);
-                    } catch (Exception e) {
-                        LOG.error("Could not create template for {}", templateClass, e);
-                    }
-                }
-            }
-        }
-    }
-
-    private void setDynMembership(final Group group, final String dynMembershipFIQL) {
+    private void setDynMembership(final Group group, final AnyTypeKind anyTypeKind, final String dynMembershipFIQL) {
         SearchCond dynMembershipCond = SearchCondConverter.convert(dynMembershipFIQL);
         if (!dynMembershipCond.isValid()) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
@@ -98,13 +55,19 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             throw sce;
         }
 
-        DynGroupMembership dynMembership;
-        if (group.getDynMembership() == null) {
-            dynMembership = entityFactory.newEntity(DynGroupMembership.class);
+        DynGroupMembership<?> dynMembership;
+        if (anyTypeKind == AnyTypeKind.ANY_OBJECT && group.getADynMembership() == null) {
+            dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
             dynMembership.setGroup(group);
-            group.setDynMembership(dynMembership);
+            group.setADynMembership((ADynGroupMembership) dynMembership);
+        } else if (anyTypeKind == AnyTypeKind.USER && group.getUDynMembership() == null) {
+            dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
+            dynMembership.setGroup(group);
+            group.setUDynMembership((UDynGroupMembership) dynMembership);
         } else {
-            dynMembership = group.getDynMembership();
+            dynMembership = anyTypeKind == AnyTypeKind.ANY_OBJECT
+                    ? group.getADynMembership()
+                    : group.getUDynMembership();
         }
         dynMembership.setFIQLCond(dynMembershipFIQL);
     }
@@ -123,16 +86,8 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             group.setName(groupTO.getName());
         }
 
-        // attribute templates
-        setAttrTemplates(group, groupTO.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class);
-        setAttrTemplates(group, groupTO.getGDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class);
-        setAttrTemplates(group, groupTO.getGVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class);
-        setAttrTemplates(group, groupTO.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class);
-        setAttrTemplates(group, groupTO.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class);
-        setAttrTemplates(group, groupTO.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
-
         // attributes, derived attributes, virtual attributes and resources
-        fill(group, groupTO, attrUtilsFactory.getInstance(AttributableType.GROUP), scce);
+        fill(group, groupTO, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce);
 
         // owner
         if (groupTO.getUserOwner() != null) {
@@ -152,8 +107,11 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             }
         }
 
-        if (groupTO.getDynMembershipCond() != null) {
-            setDynMembership(group, groupTO.getDynMembershipCond());
+        if (groupTO.getADynMembershipCond() != null) {
+            setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupTO.getADynMembershipCond());
+        }
+        if (groupTO.getADynMembershipCond() != null) {
+            setDynMembership(group, AnyTypeKind.USER, groupTO.getUDynMembershipCond());
         }
 
         return group;
@@ -169,7 +127,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         // fetch account ids before update
-        Map<String, String> oldAccountIds = getAccountIds(group, AttributableType.GROUP);
+        Map<String, String> oldConnObjectKeys = getConnObjectKeys(group);
 
         // realm
         setRealm(group, groupMod);
@@ -180,26 +138,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
             group.setName(groupMod.getName());
         }
 
-        // attribute templates
-        if (groupMod.isModGAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getGPlainAttrTemplates(), GPlainAttrTemplate.class, GPlainSchema.class);
-        }
-        if (groupMod.isModGDerAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getGDerAttrTemplates(), GDerAttrTemplate.class, GDerSchema.class);
-        }
-        if (groupMod.isModGVirAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getGVirAttrTemplates(), GVirAttrTemplate.class, GVirSchema.class);
-        }
-        if (groupMod.isModMAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class);
-        }
-        if (groupMod.isModMDerAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class);
-        }
-        if (groupMod.isModMVirAttrTemplates()) {
-            setAttrTemplates(group, groupMod.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
-        }
-
         // owner
         if (groupMod.getUserOwner() != null) {
             group.setUserOwner(groupMod.getUserOwner().getKey() == null
@@ -213,13 +151,13 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         }
 
         // attributes, derived attributes, virtual attributes and resources
-        propByRes.merge(fill(group, groupMod, attrUtilsFactory.getInstance(AttributableType.GROUP), scce));
+        propByRes.merge(fill(group, groupMod, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce));
 
         // check if some account id was changed by the update above
-        Map<String, String> newAccountIds = getAccountIds(group, AttributableType.GROUP);
-        for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) {
-            if (newAccountIds.containsKey(entry.getKey())
-                    && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) {
+        Map<String, String> newConnObjectKeys = getConnObjectKeys(group);
+        for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) {
+            if (newConnObjectKeys.containsKey(entry.getKey())
+                    && !entry.getValue().equals(newConnObjectKeys.get(entry.getKey()))) {
 
                 propByRes.addOldAccountId(entry.getKey(), entry.getValue());
                 propByRes.add(ResourceOperation.UPDATE, entry.getKey());
@@ -227,15 +165,25 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         }
 
         // dynamic membership
-        if (group.getDynMembership() != null && groupMod.getDynMembershipCond() == null) {
-            group.setDynMembership(null);
-        } else if (group.getDynMembership() == null && groupMod.getDynMembershipCond() != null) {
-            setDynMembership(group, groupMod.getDynMembershipCond());
-        } else if (group.getDynMembership() != null && groupMod.getDynMembershipCond() != null
-                && !group.getDynMembership().getFIQLCond().equals(groupMod.getDynMembershipCond())) {
-
-            group.getDynMembership().getUsers().clear();
-            setDynMembership(group, groupMod.getDynMembershipCond());
+        if (group.getADynMembership() != null && groupMod.getADynMembershipCond() == null) {
+            group.setADynMembership(null);
+        } else if (group.getADynMembership() == null && groupMod.getADynMembershipCond() != null) {
+            setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupMod.getADynMembershipCond());
+        } else if (group.getADynMembership() != null && groupMod.getADynMembershipCond() != null
+                && !group.getADynMembership().getFIQLCond().equals(groupMod.getADynMembershipCond())) {
+
+            group.getADynMembership().getMembers().clear();
+            setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupMod.getADynMembershipCond());
+        }
+        if (group.getUDynMembership() != null && groupMod.getUDynMembershipCond() == null) {
+            group.setUDynMembership(null);
+        } else if (group.getUDynMembership() == null && groupMod.getUDynMembershipCond() != null) {
+            setDynMembership(group, AnyTypeKind.USER, groupMod.getUDynMembershipCond());
+        } else if (group.getUDynMembership() != null && groupMod.getUDynMembershipCond() != null
+                && !group.getUDynMembership().getFIQLCond().equals(groupMod.getUDynMembershipCond())) {
+
+            group.getUDynMembership().getMembers().clear();
+            setDynMembership(group, AnyTypeKind.USER, groupMod.getUDynMembershipCond());
         }
 
         return propByRes;
@@ -245,7 +193,7 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
     @Transactional(readOnly = true)
     @Override
     public GroupTO getGroupTO(final Group group) {
-        connObjectUtils.retrieveVirAttrValues(group, attrUtilsFactory.getInstance(AttributableType.GROUP));
+        connObjectUtils.retrieveVirAttrValues(group);
 
         GroupTO groupTO = new GroupTO();
 
@@ -268,27 +216,11 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
         fillTO(groupTO, group.getRealm().getFullPath(),
                 group.getPlainAttrs(), group.getDerAttrs(), group.getVirAttrs(), group.getResources());
 
-        for (GPlainAttrTemplate template : group.getAttrTemplates(GPlainAttrTemplate.class)) {
-            groupTO.getGPlainAttrTemplates().add(template.getSchema().getKey());
+        if (group.getADynMembership() != null) {
+            groupTO.setADynMembershipCond(group.getADynMembership().getFIQLCond());
         }
-        for (GDerAttrTemplate template : group.getAttrTemplates(GDerAttrTemplate.class)) {
-            groupTO.getGDerAttrTemplates().add(template.getSchema().getKey());
-        }
-        for (GVirAttrTemplate template : group.getAttrTemplates(GVirAttrTemplate.class)) {
-            groupTO.getGVirAttrTemplates().add(template.getSchema().getKey());
-        }
-        for (MPlainAttrTemplate template : group.getAttrTemplates(MPlainAttrTemplate.class)) {
-            groupTO.getMPlainAttrTemplates().add(template.getSchema().getKey());
-        }
-        for (MDerAttrTemplate template : group.getAttrTemplates(MDerAttrTemplate.class)) {
-            groupTO.getMDerAttrTemplates().add(template.getSchema().getKey());
-        }
-        for (MVirAttrTemplate template : group.getAttrTemplates(MVirAttrTemplate.class)) {
-            groupTO.getMVirAttrTemplates().add(template.getSchema().getKey());
-        }
-
-        if (group.getDynMembership() != null) {
-            groupTO.setDynMembershipCond(group.getDynMembership().getFIQLCond());
+        if (group.getUDynMembership() != null) {
+            groupTO.setUDynMembershipCond(group.getUDynMembership().getFIQLCond());
         }
 
         return groupTO;
@@ -297,6 +229,6 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
     @Transactional(readOnly = true)
     @Override
     public GroupTO getGroupTO(final Long key) {
-        return getGroupTO(groupDAO.authFetch(key));
+        return getGroupTO(groupDAO.authFind(key));
     }
 }


[06/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index d21afc5..400b72e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -26,29 +26,19 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -59,6 +49,14 @@ import org.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.MappingUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+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.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -78,6 +76,8 @@ public class PropagationManagerImpl implements PropagationManager {
      */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
+    protected AnyObjectDAO anyObjectDAO;
+
     /**
      * User DAO.
      */
@@ -106,39 +106,38 @@ public class PropagationManagerImpl implements PropagationManager {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
     protected VirAttrHandler virAttrHandler;
 
     @Override
+    public List<PropagationTask> getAnyObjectCreateTasks(
+            final Long key,
+            final Collection<AttrTO> vAttrs,
+            final PropagationByResource propByRes,
+            final List<String> noPropResourceNames) {
+
+        AnyObject anyObject = anyObjectDAO.authFind(key);
+        if (vAttrs != null && !vAttrs.isEmpty()) {
+            virAttrHandler.fillVirtual(anyObject, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        }
+
+        return getCreateTaskIds(anyObject, null, null, propByRes, noPropResourceNames);
+    }
+
+    @Override
     public List<PropagationTask> getUserCreateTasks(
             final Long key,
             final Boolean enable,
             final PropagationByResource propByRes,
             final String password,
             final Collection<AttrTO> vAttrs,
-            final Collection<MembershipTO> membershipTOs,
             final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(key);
+        User user = userDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(user, vAttrs, attrUtilsFactory.getInstance(AttributableType.USER));
-        }
-        for (final Membership membership : user.getMemberships()) {
-            if (membership.getVirAttrs() != null && !membership.getVirAttrs().isEmpty()) {
-                MembershipTO membershipTO = CollectionUtils.find(membershipTOs, new Predicate<MembershipTO>() {
-
-                    @Override
-                    public boolean evaluate(final MembershipTO membershipTO) {
-                        return membershipTO.getGroupKey() == membership.getGroup().getKey();
-                    }
-                });
-                if (membershipTO != null) {
-                    virAttrHandler.fillVirtual(membership,
-                            membershipTO.getVirAttrs(), attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
-                }
-            }
+            virAttrHandler.fillVirtual(user, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.USER));
         }
         return getCreateTaskIds(user, password, enable, propByRes, noPropResourceNames);
     }
@@ -176,15 +175,15 @@ public class PropagationManagerImpl implements PropagationManager {
             final PropagationByResource propByRes,
             final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(key);
+        Group group = groupDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(group, vAttrs, attrUtilsFactory.getInstance(AttributableType.GROUP));
+            virAttrHandler.fillVirtual(group, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
         }
 
         return getCreateTaskIds(group, null, null, propByRes, noPropResourceNames);
     }
 
-    protected List<PropagationTask> getCreateTaskIds(final Subject<?, ?, ?> subject,
+    protected List<PropagationTask> getCreateTaskIds(final Any<?, ?, ?> any,
             final String password, final Boolean enable,
             final PropagationByResource propByRes,
             final Collection<String> noPropResourceNames) {
@@ -197,7 +196,7 @@ public class PropagationManagerImpl implements PropagationManager {
             propByRes.get(ResourceOperation.CREATE).removeAll(noPropResourceNames);
         }
 
-        return createTasks(subject, password, true, null, null, null, null, enable, false, propByRes);
+        return createTasks(any, password, true, null, null, enable, false, propByRes);
     }
 
     /**
@@ -220,8 +219,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 Collections.<String>emptySet(), // no virtual attributes to be managed
                 Collections.<AttrMod>emptySet(), // no virtual attributes to be managed
                 null, // no propagation by resources
-                noPropResourceNames,
-                Collections.<MembershipMod>emptySet());
+                noPropResourceNames);
     }
 
     /**
@@ -236,7 +234,7 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getUserUpdateTasks(final WorkflowResult<Pair<UserMod, Boolean>> wfResult,
             final boolean changePwd, final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(wfResult.getResult().getKey().getKey());
+        User user = userDAO.authFind(wfResult.getResult().getKey().getKey());
         return getUpdateTasks(user,
                 wfResult.getResult().getKey().getPassword(),
                 changePwd,
@@ -244,8 +242,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 wfResult.getResult().getKey().getVirAttrsToRemove(),
                 wfResult.getResult().getKey().getVirAttrsToUpdate(),
                 wfResult.getPropByRes(),
-                noPropResourceNames,
-                wfResult.getResult().getKey().getMembershipsToAdd());
+                noPropResourceNames);
     }
 
     @Override
@@ -264,7 +261,7 @@ public class PropagationManagerImpl implements PropagationManager {
             origPropByRes.merge(wfResult.getPropByRes());
 
             Set<String> pwdResourceNames = new HashSet<>(userMod.getPwdPropRequest().getResourceNames());
-            Collection<String> currentResourceNames = userDAO.findAllResourceNames(userDAO.authFetch(userMod.getKey()));
+            Collection<String> currentResourceNames = userDAO.findAllResourceNames(userDAO.authFind(userMod.getKey()));
             pwdResourceNames.retainAll(currentResourceNames);
             PropagationByResource pwdPropByRes = new PropagationByResource();
             pwdPropByRes.addAll(ResourceOperation.UPDATE, pwdResourceNames);
@@ -292,55 +289,25 @@ public class PropagationManagerImpl implements PropagationManager {
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
             final Set<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(wfResult.getResult());
+        Group group = groupDAO.authFind(wfResult.getResult());
         return getUpdateTasks(group, null, false, null,
-                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames,
-                Collections.<MembershipMod>emptySet());
+                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames);
     }
 
     @Override
-    public List<PropagationTask> getUpdateTasks(final Subject<?, ?, ?> subject,
+    public List<PropagationTask> getUpdateTasks(final Any<?, ?, ?> any,
             final String password, final boolean changePwd, final Boolean enable,
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
-            final PropagationByResource propByRes, final Collection<String> noPropResourceNames,
-            final Set<MembershipMod> membershipsToAdd) {
+            final PropagationByResource propByRes, final Collection<String> noPropResourceNames) {
 
-        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(subject, vAttrsToBeRemoved == null
+        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(any, vAttrsToBeRemoved == null
                 ? Collections.<String>emptySet()
                 : vAttrsToBeRemoved, vAttrsToBeUpdated == null
                         ? Collections.<AttrMod>emptySet()
-                        : vAttrsToBeUpdated, attrUtilsFactory.getInstance(subject));
-
-        // SYNCOPE-458 fill membership virtual attributes
-        Collection<String> resourceNames;
-        if (subject instanceof User) {
-            User user = (User) subject;
-            resourceNames = userDAO.findAllResourceNames(user);
-            for (final Membership membership : user.getMemberships()) {
-                if (membership.getVirAttrs() != null && !membership.getVirAttrs().isEmpty()) {
-                    MembershipMod membMod = CollectionUtils.find(membershipsToAdd, new Predicate<MembershipMod>() {
-
-                        @Override
-                        public boolean evaluate(final MembershipMod membershipMod) {
-                            return membershipMod.getGroup() == membership.getGroup().getKey();
-                        }
-                    });
-                    if (membMod != null) {
-                        virAttrHandler.fillVirtual(membership, membMod.getVirAttrsToRemove() == null
-                                ? Collections.<String>emptySet()
-                                : membMod.getVirAttrsToRemove(),
-                                membMod.getVirAttrsToUpdate() == null ? Collections.<AttrMod>emptySet()
-                                        : membMod.getVirAttrsToUpdate(), attrUtilsFactory.getInstance(
-                                        AttributableType.MEMBERSHIP));
-                    }
-                }
-            }
-        } else {
-            resourceNames = subject.getResourceNames();
-        }
+                        : vAttrsToBeUpdated, anyUtilsFactory.getInstance(any));
 
         if (propByRes == null || propByRes.isEmpty()) {
-            localPropByRes.addAll(ResourceOperation.UPDATE, resourceNames);
+            localPropByRes.addAll(ResourceOperation.UPDATE, any.getResourceNames());
         } else {
             localPropByRes.merge(propByRes);
         }
@@ -357,29 +324,26 @@ public class PropagationManagerImpl implements PropagationManager {
             }
         }
 
-        // SYNCOPE-458 fill membership virtual attributes to be updated map
-        Map<String, AttrMod> membVAttrsToBeUpdatedMap = new HashMap<>();
-        for (MembershipMod membershipMod : membershipsToAdd) {
-            for (AttrMod attrMod : membershipMod.getVirAttrsToUpdate()) {
-                membVAttrsToBeUpdatedMap.put(attrMod.getSchema(), attrMod);
-            }
-        }
+        return createTasks(
+                any, password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdatedMap, enable, false, localPropByRes);
+    }
 
-        // SYNCOPE-458 fill membership virtual attributes to be removed set
-        final Set<String> membVAttrsToBeRemoved = new HashSet<>();
-        for (MembershipMod membershipMod : membershipsToAdd) {
-            membVAttrsToBeRemoved.addAll(membershipMod.getVirAttrsToRemove());
-        }
+    @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(final Long anyObjectKey, final String noPropResourceName) {
+        return getAnyObjectDeleteTasks(anyObjectKey, Collections.<String>singleton(noPropResourceName));
+    }
+
+    @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(
+            final Long anyObjectKey, final Collection<String> noPropResourceNames) {
 
-        return createTasks(subject, password, changePwd,
-                vAttrsToBeRemoved, vAttrsToBeUpdatedMap, membVAttrsToBeRemoved, membVAttrsToBeUpdatedMap, enable, false,
-                localPropByRes);
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        return getDeleteTaskIds(anyObject, anyObject.getResourceNames(), noPropResourceNames);
     }
 
     @Override
     public List<PropagationTask> getUserDeleteTasks(final Long userKey, final Collection<String> noPropResourceNames) {
-
-        User user = userDAO.authFetch(userKey);
+        User user = userDAO.authFind(userKey);
         return getDeleteTaskIds(user, userDAO.findAllResourceNames(user), noPropResourceNames);
     }
 
@@ -387,25 +351,23 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getUserDeleteTasks(
             final Long userKey, final Set<String> resourceNames, final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(userKey);
+        User user = userDAO.authFind(userKey);
         return getDeleteTaskIds(user, resourceNames, noPropResourceNames);
     }
 
     @Override
     public List<PropagationTask> getUserDeleteTasks(final WorkflowResult<Long> wfResult) {
-        User user = userDAO.authFetch(wfResult.getResult());
-        return createTasks(user, null, false, null, null, null, null, false, true, wfResult.getPropByRes());
+        User user = userDAO.authFind(wfResult.getResult());
+        return createTasks(user, null, false, null, null, false, true, wfResult.getPropByRes());
     }
 
     @Override
     public List<PropagationTask> getGroupDeleteTasks(final Long groupKey) {
-
         return getGroupDeleteTasks(groupKey, Collections.<String>emptySet());
     }
 
     @Override
     public List<PropagationTask> getGroupDeleteTasks(final Long groupKey, final String noPropResourceName) {
-
         return getGroupDeleteTasks(groupKey, Collections.<String>singleton(noPropResourceName));
     }
 
@@ -413,7 +375,7 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getGroupDeleteTasks(
             final Long groupKey, final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
         return getDeleteTaskIds(group, group.getResourceNames(), noPropResourceNames);
     }
 
@@ -421,12 +383,12 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getGroupDeleteTasks(
             final Long groupKey, final Set<String> resourceNames, final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
         return getDeleteTaskIds(group, resourceNames, noPropResourceNames);
     }
 
     protected List<PropagationTask> getDeleteTaskIds(
-            final Subject<?, ?, ?> subject,
+            final Any<?, ?, ?> any,
             final Collection<String> resourceNames,
             final Collection<String> noPropResourceNames) {
 
@@ -435,41 +397,38 @@ public class PropagationManagerImpl implements PropagationManager {
         if (noPropResourceNames != null && !noPropResourceNames.isEmpty()) {
             propByRes.get(ResourceOperation.DELETE).removeAll(noPropResourceNames);
         }
-        return createTasks(subject, null, false, null, null, null, null, false, true, propByRes);
+        return createTasks(any, null, false, null, null, false, true, propByRes);
     }
 
     /**
      * Create propagation tasks.
      *
-     * @param subject user / group to be provisioned
+     * @param any user / group to be provisioned
      * @param password cleartext password to be provisioned
      * @param changePwd whether password should be included for propagation attributes or not
      * @param vAttrsToBeRemoved virtual attributes to be removed
      * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param membVAttrsToBeRemoved membership virtual attributes to be removed
-     * @param membVAttrsToBeUpdatedMap membership virtual attributes to be added
      * @param enable whether user must be enabled or not
      * @param deleteOnResource whether user / group must be deleted anyway from external resource or not
      * @param propByRes operation to be performed per resource
      * @return list of propagation tasks created
      */
-    protected List<PropagationTask> createTasks(final Subject<?, ?, ?> subject,
+    protected List<PropagationTask> createTasks(final Any<?, ?, ?> any,
             final String password, final boolean changePwd,
             final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated,
-            final Set<String> membVAttrsToBeRemoved, final Map<String, AttrMod> membVAttrsToBeUpdatedMap,
             final Boolean enable, final boolean deleteOnResource, final PropagationByResource propByRes) {
 
-        LOG.debug("Provisioning subject {}:\n{}", subject, propByRes);
+        LOG.debug("Provisioning any {}:\n{}", any, propByRes);
 
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(subject);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
         if (!propByRes.get(ResourceOperation.CREATE).isEmpty()
                 && vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
 
-            connObjectUtils.retrieveVirAttrValues(subject, attrUtils);
+            connObjectUtils.retrieveVirAttrValues(any);
 
             // update vAttrsToBeUpdated as well
-            for (VirAttr virAttr : subject.getVirAttrs()) {
+            for (VirAttr<?> virAttr : any.getVirAttrs()) {
                 final String schema = virAttr.getSchema().getKey();
 
                 final AttrMod attributeMod = new AttrMod();
@@ -488,36 +447,39 @@ public class PropagationManagerImpl implements PropagationManager {
 
         for (ResourceOperation operation : ResourceOperation.values()) {
             for (String resourceName : propByRes.get(operation)) {
-                final ExternalResource resource = resourceDAO.find(resourceName);
+                ExternalResource resource = resourceDAO.find(resourceName);
+                Provision provision = resource == null ? null : resource.getProvision(any.getType());
                 if (resource == null) {
                     LOG.error("Invalid resource name specified: {}, ignoring...", resourceName);
-                } else if (attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION).isEmpty()) {
+                } else if (provision == null) {
+                    LOG.error("No provision specified on resource {} for type {}, ignoring...",
+                            resource, any.getType());
+                } else if (anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION).isEmpty()) {
                     LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}",
-                            attrUtils.getType(), resource);
+                            any.getType(), resource);
                 } else {
                     PropagationTask task = entityFactory.newEntity(PropagationTask.class);
                     task.setResource(resource);
-                    task.setObjectClassName(connObjectUtils.fromSubject(subject).getObjectClassValue());
-                    task.setSubjectType(attrUtils.getType());
+                    task.setObjectClassName(resource.getProvision(any.getType()).getObjectClass().getObjectClassValue());
+                    task.setAnyTypeKind(anyUtils.getAnyTypeKind());
                     if (!deleteOnResource) {
-                        task.setSubjectKey(subject.getKey());
+                        task.setAnyKey(any.getKey());
                     }
                     task.setPropagationOperation(operation);
                     task.setPropagationMode(resource.getPropagationMode());
-                    task.setOldAccountId(propByRes.getOldAccountId(resource.getKey()));
+                    task.setOldConnObjectKey(propByRes.getOldAccountId(resource.getKey()));
 
-                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(attrUtils, subject,
-                            password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, membVAttrsToBeRemoved,
-                            membVAttrsToBeUpdatedMap, enable, resource);
-                    task.setAccountId(preparedAttrs.getKey());
+                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(anyUtils, any,
+                            password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, enable, provision);
+                    task.setConnObjectKey(preparedAttrs.getKey());
 
                     // Check if any of mandatory attributes (in the mapping) is missing or not received any value: 
                     // if so, add special attributes that will be evaluated by PropagationTaskExecutor
                     List<String> mandatoryMissing = new ArrayList<>();
                     List<String> mandatoryNullOrEmpty = new ArrayList<>();
-                    for (MappingItem item : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
-                        if (!item.isAccountid()
-                                && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), subject)) {
+                    for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+                        if (!item.isConnObjectKey()
+                                && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
 
                             Attribute attr = AttributeUtil.find(item.getExtAttrName(), preparedAttrs.getValue());
                             if (attr == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
index 9373249..2c04f26 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
+import static org.apache.syncope.common.lib.types.AnyTypeKind.USER;
+
 import java.lang.reflect.ParameterizedType;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,12 +30,14 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+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.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+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.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
@@ -63,6 +67,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
     @Autowired
     protected ConnectorFactory connFactory;
 
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
     /**
      * Resource DAO.
      */
@@ -121,13 +128,23 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
         List<ProvisioningResult> gFailDelete = new ArrayList<>();
         List<ProvisioningResult> gSuccNone = new ArrayList<>();
         List<ProvisioningResult> gIgnore = new ArrayList<>();
+        List<ProvisioningResult> aSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> aFailCreate = new ArrayList<>();
+        List<ProvisioningResult> aSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> aFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> aSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> aFailDelete = new ArrayList<>();
+        List<ProvisioningResult> aSuccNone = new ArrayList<>();
+        List<ProvisioningResult> aIgnore = new ArrayList<>();
 
         for (ProvisioningResult provResult : provResults) {
+            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
+
             switch (provResult.getStatus()) {
                 case SUCCESS:
                     switch (provResult.getOperation()) {
                         case CREATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccCreate.add(provResult);
                                     break;
@@ -136,12 +153,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccCreate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccCreate.add(provResult);
                             }
                             break;
 
                         case UPDATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccUpdate.add(provResult);
                                     break;
@@ -150,12 +169,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccUpdate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccUpdate.add(provResult);
                             }
                             break;
 
                         case DELETE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccDelete.add(provResult);
                                     break;
@@ -164,12 +185,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccDelete.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccDelete.add(provResult);
                             }
                             break;
 
                         case NONE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccNone.add(provResult);
                                     break;
@@ -178,7 +201,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccNone.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccNone.add(provResult);
                             }
                             break;
 
@@ -189,7 +214,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 case FAILURE:
                     switch (provResult.getOperation()) {
                         case CREATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailCreate.add(provResult);
                                     break;
@@ -198,12 +223,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailCreate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailCreate.add(provResult);
                             }
                             break;
 
                         case UPDATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailUpdate.add(provResult);
                                     break;
@@ -212,12 +239,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailUpdate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailUpdate.add(provResult);
                             }
                             break;
 
                         case DELETE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailDelete.add(provResult);
                                     break;
@@ -226,7 +255,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailDelete.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailDelete.add(provResult);
                             }
                             break;
 
@@ -235,7 +266,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     break;
 
                 case IGNORE:
-                    switch (provResult.getSubjectType()) {
+                    switch (anyType.getKind()) {
                         case USER:
                             uIgnore.add(provResult);
                             break;
@@ -244,7 +275,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                             gIgnore.add(provResult);
                             break;
 
+                        case ANY_OBJECT:
                         default:
+                            aIgnore.add(provResult);
                     }
                     break;
 
@@ -270,6 +303,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
                 append(' ').
                 append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size());
+        report.append("Any objects ").
+                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
 
         // Failures
         if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
@@ -298,6 +339,19 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 report.append("\nGroups failed to delete: ");
                 report.append(ProvisioningResult.produceReport(gFailDelete, syncTraceLevel));
             }
+
+            if (!aFailCreate.isEmpty()) {
+                report.append("\nAny objects failed to create: ");
+                report.append(ProvisioningResult.produceReport(aFailCreate, syncTraceLevel));
+            }
+            if (!aFailUpdate.isEmpty()) {
+                report.append("\nAny objects failed to update: ");
+                report.append(ProvisioningResult.produceReport(aFailUpdate, syncTraceLevel));
+            }
+            if (!aFailDelete.isEmpty()) {
+                report.append("\nAny objects failed to delete: ");
+                report.append(ProvisioningResult.produceReport(aFailDelete, syncTraceLevel));
+            }
         }
 
         // Succeeded, only if on 'ALL' level
@@ -322,6 +376,16 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel)).
                     append("\nGroups ignored:\n").
                     append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel));
+            report.append("\n\nAny objects created:\n").
+                    append(ProvisioningResult.produceReport(aSuccCreate, syncTraceLevel)).
+                    append("\nAny objects updated:\n").
+                    append(ProvisioningResult.produceReport(aSuccUpdate, syncTraceLevel)).
+                    append("\nAny objects deleted:\n").
+                    append(ProvisioningResult.produceReport(aSuccDelete, syncTraceLevel)).
+                    append("\nAny objects no operation:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel)).
+                    append("\nAny objects ignored:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel));
         }
 
         return report.toString();
@@ -339,49 +403,48 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     }
                 }, new ArrayList<GrantedAuthority>());
 
-        final UserDetails userDetails = new User("admin", "FAKE_PASSWORD", authorities);
+        UserDetails userDetails = new User("admin", "FAKE_PASSWORD", authorities);
 
         SecurityContextHolder.getContext().setAuthentication(
                 new UsernamePasswordAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities));
 
         try {
-            final Class<T> clazz = getTaskClassReference();
+            Class<T> clazz = getTaskClassReference();
             if (!clazz.isAssignableFrom(task.getClass())) {
                 throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
             }
 
-            final T syncTask = clazz.cast(this.task);
+            T _task = clazz.cast(this.task);
 
-            final Connector connector;
+            Connector connector;
             try {
-                connector = connFactory.getConnector(syncTask.getResource());
+                connector = connFactory.getConnector(_task.getResource());
             } catch (Exception e) {
                 final String msg = String.
                         format("Connector instance bean for resource %s and connInstance %s not found",
-                                syncTask.getResource(), syncTask.getResource().getConnector());
+                                _task.getResource(), _task.getResource().getConnector());
 
                 throw new JobExecutionException(msg, e);
             }
 
-            final UMapping uMapping = syncTask.getResource().getUmapping();
-            if (uMapping != null && uMapping.getAccountIdItem() == null) {
-                throw new JobExecutionException(
-                        "Invalid user account id mapping for resource " + syncTask.getResource());
-            }
-            final GMapping rMapping = syncTask.getResource().getGmapping();
-            if (rMapping != null && rMapping.getAccountIdItem() == null) {
-                throw new JobExecutionException(
-                        "Invalid group account id mapping for resource " + syncTask.getResource());
+            boolean noMapping = true;
+            for (Provision provision : _task.getResource().getProvisions()) {
+                Mapping mapping = provision.getMapping();
+                if (mapping != null) {
+                    noMapping = false;
+                    if (mapping.getConnObjectKeyItem() == null) {
+                        throw new JobExecutionException(
+                                "Invalid ConnObjectKey mapping for provision " + provision);
+                    }
+                }
             }
-            if (uMapping == null && rMapping == null) {
+            if (noMapping) {
                 return "No mapping configured for both users and groups: aborting...";
             }
 
             return executeWithSecurityContext(
-                    syncTask,
+                    _task,
                     connector,
-                    uMapping,
-                    rMapping,
                     dryRun);
         } catch (Throwable t) {
             LOG.error("While executing provisioning job {}", getClass().getName(), t);
@@ -395,8 +458,6 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
     protected abstract String executeWithSecurityContext(
             final T task,
             final Connector connector,
-            final UMapping uMapping,
-            final GMapping rMapping,
             final boolean dryRun) throws JobExecutionException;
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
index e15f526..275f648 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.IntMappingType;
@@ -33,57 +32,59 @@ import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.quartz.JobExecutionException;
 import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
         implements SyncopePushResultHandler {
 
-    protected abstract String getName(Subject<?, ?, ?> subject);
+    protected abstract String getName(Any<?, ?, ?> any);
 
-    protected abstract Mapping<?> getMapping();
+    protected abstract Any<?, ?, ?> getAny(long key);
 
-    protected abstract Subject<?, ?, ?> getSubject(long key);
+    protected abstract Any<?, ?, ?> deprovision(Any<?, ?, ?> sbj);
 
-    protected abstract Subject<?, ?, ?> deprovision(Subject<?, ?, ?> sbj);
+    protected abstract Any<?, ?, ?> provision(Any<?, ?, ?> sbj, Boolean enabled);
 
-    protected abstract Subject<?, ?, ?> provision(Subject<?, ?, ?> sbj, Boolean enabled);
+    protected abstract Any<?, ?, ?> link(Any<?, ?, ?> sbj, Boolean unlink);
 
-    protected abstract Subject<?, ?, ?> link(Subject<?, ?, ?> sbj, Boolean unlink);
+    protected abstract Any<?, ?, ?> unassign(Any<?, ?, ?> sbj);
 
-    protected abstract Subject<?, ?, ?> unassign(Subject<?, ?, ?> sbj);
+    protected abstract Any<?, ?, ?> assign(Any<?, ?, ?> sbj, Boolean enabled);
 
-    protected abstract Subject<?, ?, ?> assign(Subject<?, ?, ?> sbj, Boolean enabled);
-
-    protected abstract ConnectorObject getRemoteObject(String accountId);
+    protected abstract ConnectorObject getRemoteObject(String connObjectKey, ObjectClass objectClass);
 
     @Transactional
     @Override
-    public boolean handle(final long subjectKey) {
+    public boolean handle(final long anyKey) {
+        Any<?, ?, ?> any = null;
         try {
-            doHandle(subjectKey);
+            any = getAny(anyKey);
+            doHandle(any);
             return true;
         } catch (IgnoreProvisionException e) {
             ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(getAttributableUtils().getType());
+            result.setAnyType(any == null ? null : any.getType().getKey());
             result.setStatus(ProvisioningResult.Status.IGNORE);
-            result.setKey(subjectKey);
+            result.setKey(anyKey);
             profile.getResults().add(result);
 
             LOG.warn("Ignoring during push", e);
@@ -94,26 +95,24 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected final void doHandle(final long subjectId)
+    protected final void doHandle(final Any<?, ?, ?> any)
             throws JobExecutionException {
 
-        Subject<?, ?, ?> subject = getSubject(subjectId);
-
-        AttributableUtils attrUtils = attrUtilsFactory.getInstance(subject);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
         ProvisioningResult result = new ProvisioningResult();
         profile.getResults().add(result);
 
-        result.setKey(subject.getKey());
-        result.setSubjectType(attrUtils.getType());
-        result.setName(getName(subject));
+        result.setKey(any.getKey());
+        result.setAnyType(any.getType().getKey());
+        result.setName(getName(any));
 
-        Boolean enabled = subject instanceof User && profile.getTask().isSyncStatus()
-                ? ((User) subject).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+        Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
+                ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
                 : null;
 
         LOG.debug("Propagating {} with key {} towards {}",
-                attrUtils.getType(), subject.getKey(), profile.getTask().getResource());
+                anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
 
         Object output = null;
         Result resultStatus = null;
@@ -121,10 +120,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         String operation = null;
 
         // Try to read remote object (user / group) BEFORE any actual operation
-        String accountId = MappingUtils.getAccountIdValue(
-                subject, profile.getTask().getResource(), getMapping().getAccountIdItem());
+        Provision provision = profile.getTask().getResource().getProvision(any.getType());
+        String connObjecKey = MappingUtils.getConnObjectKeyValue(any, provision);
 
-        beforeObj = getRemoteObject(accountId);
+        beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
 
         Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
 
@@ -144,42 +143,45 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeAssign(this.getProfile(), subject);
+                                action.beforeAssign(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
                             } else {
-                                assign(subject, status);
+                                assign(any, status);
                             }
 
                             break;
+
                         case PROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeProvision(this.getProfile(), subject);
+                                action.beforeProvision(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
                             } else {
-                                provision(subject, status);
+                                provision(any, status);
                             }
 
                             break;
+
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), subject);
+                                action.beforeUnlink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, true);
+                                link(any, true);
                             }
 
                             break;
+
                         case IGNORE:
-                            LOG.debug("Ignored subjectId: {}", subjectId);
+                            LOG.debug("Ignored any: {}", any);
                             break;
                         default:
                         // do nothing
@@ -192,65 +194,70 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUpdate(this.getProfile(), subject);
+                                action.beforeUpdate(this.getProfile(), any);
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                update(subject, status);
+                                update(any, status);
                             }
 
                             break;
+
                         case DEPROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), subject);
+                                action.beforeDeprovision(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
                             } else {
-                                deprovision(subject);
+                                deprovision(any);
                             }
 
                             break;
+
                         case UNASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), subject);
+                                action.beforeUnassign(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
                             } else {
-                                unassign(subject);
+                                unassign(any);
                             }
 
                             break;
+
                         case LINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), subject);
+                                action.beforeLink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, false);
+                                link(any, false);
                             }
 
                             break;
+
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), subject);
+                                action.beforeUnlink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, true);
+                                link(any, true);
                             }
 
                             break;
+
                         case IGNORE:
-                            LOG.debug("Ignored subjectId: {}", subjectId);
+                            LOG.debug("Ignored any: {}", any);
                             break;
                         default:
                         // do nothing
@@ -258,12 +265,12 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                 }
 
                 for (PushActions action : profile.getActions()) {
-                    action.after(this.getProfile(), subject, result);
+                    action.after(this.getProfile(), any, result);
                 }
 
                 result.setStatus(ProvisioningResult.Status.SUCCESS);
                 resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(accountId);
+                output = getRemoteObject(connObjecKey, provision.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
@@ -272,30 +279,30 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                 resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
-                LOG.warn("Error pushing {} towards {}", subject, profile.getTask().getResource(), e);
+                LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
 
                 for (PushActions action : profile.getActions()) {
-                    action.onError(this.getProfile(), subject, result, e);
+                    action.onError(this.getProfile(), any, result, e);
                 }
 
                 throw new JobExecutionException(e);
             } finally {
                 notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
-                        getAttributableUtils().getType().name().toLowerCase(),
+                        any.getType().getKind().name().toLowerCase(),
                         profile.getTask().getResource().getKey(),
                         operation,
                         resultStatus,
                         beforeObj,
                         output,
-                        subject);
+                        any);
                 auditManager.audit(AuditElements.EventCategoryType.PUSH,
-                        getAttributableUtils().getType().name().toLowerCase(),
+                        any.getType().getKind().name().toLowerCase(),
                         profile.getTask().getResource().getKey(),
                         operation,
                         resultStatus,
                         beforeObj,
                         output,
-                        subject);
+                        any);
             }
         }
     }
@@ -322,28 +329,24 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected Subject<?, ?, ?> update(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final Set<MembershipMod> membsToAdd = new HashSet<>();
-        final Set<String> vattrToBeRemoved = new HashSet<>();
-        final Set<String> membVattrToBeRemoved = new HashSet<>();
-        final Set<AttrMod> vattrToBeUpdated = new HashSet<>();
+    protected Any<?, ?, ?> update(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        Set<String> vattrToBeRemoved = new HashSet<>();
+        Set<AttrMod> vattrToBeUpdated = new HashSet<>();
 
         // Search for all mapped vattrs
-        final Mapping<?> umapping = getMapping();
-        for (MappingItem mappingItem : umapping.getItems()) {
+        Mapping mapping = profile.getTask().getResource().getProvision(sbj.getType()).getMapping();
+        for (MappingItem mappingItem : mapping.getItems()) {
             if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) {
                 vattrToBeRemoved.add(mappingItem.getIntAttrName());
-            } else if (mappingItem.getIntMappingType() == IntMappingType.MembershipVirtualSchema) {
-                membVattrToBeRemoved.add(mappingItem.getIntAttrName());
             }
         }
 
         // Search for all user's vattrs and:
         // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed
         // 2. add all vattrs owned by the user to the set of vattrs to be update
-        for (VirAttr vattr : sbj.getVirAttrs()) {
+        for (VirAttr<?> vattr : sbj.getVirAttrs()) {
             vattrToBeRemoved.remove(vattr.getSchema().getKey());
-            final AttrMod mod = new AttrMod();
+            AttrMod mod = new AttrMod();
             mod.setSchema(vattr.getSchema().getKey());
             mod.getValuesToBeAdded().addAll(vattr.getValues());
             vattrToBeUpdated.add(mod);
@@ -354,27 +357,9 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         if (sbj instanceof User) {
             changepwd = true;
             resourceNames = userDAO.findAllResourceNames((User) sbj);
-
-            // Search for memberships
-            for (Membership membership : User.class.cast(sbj).getMemberships()) {
-                MembershipMod membershipMod = new MembershipMod();
-                membershipMod.setKey(membership.getKey());
-                membershipMod.setGroup(membership.getGroup().getKey());
-
-                for (VirAttr vattr : membership.getVirAttrs()) {
-                    membVattrToBeRemoved.remove(vattr.getSchema().getKey());
-                    AttrMod mod = new AttrMod();
-                    mod.setSchema(vattr.getSchema().getKey());
-                    mod.getValuesToBeAdded().addAll(vattr.getValues());
-                    membershipMod.getVirAttrsToUpdate().add(mod);
-                }
-
-                membsToAdd.add(membershipMod);
-            }
-
-            if (!membsToAdd.isEmpty()) {
-                membsToAdd.iterator().next().getVirAttrsToRemove().addAll(membVattrToBeRemoved);
-            }
+        } else if (sbj instanceof AnyObject) {
+            changepwd = true;
+            resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) sbj);
         } else {
             changepwd = false;
             resourceNames = ((Group) sbj).getResourceNames();
@@ -387,9 +372,8 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getUpdateTasks(
-                sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources,
-                membsToAdd));
+                sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources));
 
-        return userDAO.authFetch(sbj.getKey());
+        return getAny(sbj.getKey());
     }
 }


[28/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
new file mode 100644
index 0000000..cab3239
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
@@ -0,0 +1,375 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.ReferenceMod;
+import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+/**
+ * Utility class for comparing manipulating {@link AnyTO} and {@link AnyMod}.
+ */
+public final class AnyOperations {
+
+    private AnyOperations() {
+        // empty constructor for static utility classes
+    }
+
+    private static void populate(final Map<String, AttrTO> updatedAttrs,
+            final Map<String, AttrTO> originalAttrs, final AnyMod result) {
+
+        populate(updatedAttrs, originalAttrs, result, false);
+    }
+
+    private static void populate(final Map<String, AttrTO> updatedAttrs,
+            final Map<String, AttrTO> originalAttrs, final AnyMod result,
+            final boolean virtuals) {
+
+        for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
+            AttrMod mod = new AttrMod();
+            mod.setSchema(entry.getKey());
+
+            Set<String> updatedValues = new HashSet<>(entry.getValue().getValues());
+
+            Set<String> originalValues = originalAttrs.containsKey(entry.getKey())
+                    ? new HashSet<>(originalAttrs.get(entry.getKey()).getValues())
+                    : Collections.<String>emptySet();
+
+            if (!originalAttrs.containsKey(entry.getKey())) {
+                // SYNCOPE-459: take care of user virtual attributes without any value
+                updatedValues.remove("");
+                mod.getValuesToBeAdded().addAll(new ArrayList<>(updatedValues));
+
+                if (virtuals) {
+                    result.getVirAttrsToUpdate().add(mod);
+                } else {
+                    result.getPlainAttrsToUpdate().add(mod);
+                }
+            } else if (!updatedValues.equals(originalValues)) {
+                // avoid unwanted inputs
+                updatedValues.remove("");
+                if (!entry.getValue().isReadonly()) {
+                    mod.getValuesToBeAdded().addAll(updatedValues);
+
+                    if (!mod.isEmpty()) {
+                        if (virtuals) {
+                            result.getVirAttrsToRemove().add(mod.getSchema());
+                        } else {
+                            result.getPlainAttrsToRemove().add(mod.getSchema());
+                        }
+                    }
+                }
+
+                mod.getValuesToBeRemoved().addAll(originalValues);
+
+                if (!mod.isEmpty()) {
+                    if (virtuals) {
+                        result.getVirAttrsToUpdate().add(mod);
+                    } else {
+                        result.getPlainAttrsToUpdate().add(mod);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void diff(
+            final AnyTO updated,
+            final AnyTO original,
+            final AnyMod result,
+            final boolean incremental) {
+
+        // 1. check same id
+        if (updated.getKey() != original.getKey()) {
+            throw new IllegalArgumentException("AnyTO's id must be the same");
+        }
+        result.setKey(updated.getKey());
+
+        // 2. attributes
+        Map<String, AttrTO> updatedAttrs = new HashMap<>(updated.getPlainAttrMap());
+        Map<String, AttrTO> originalAttrs = new HashMap<>(original.getPlainAttrMap());
+
+        Set<String> originalAttrNames = new HashSet<>(originalAttrs.keySet());
+        originalAttrNames.removeAll(updatedAttrs.keySet());
+
+        if (!incremental) {
+            result.getPlainAttrsToRemove().clear();
+            result.getPlainAttrsToRemove().addAll(originalAttrNames);
+        }
+
+        Set<String> emptyUpdatedAttrs = new HashSet<>();
+        for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
+            if (entry.getValue().getValues() == null || entry.getValue().getValues().isEmpty()) {
+
+                emptyUpdatedAttrs.add(entry.getKey());
+            }
+        }
+        for (String emptyUpdatedAttr : emptyUpdatedAttrs) {
+            updatedAttrs.remove(emptyUpdatedAttr);
+            result.getPlainAttrsToRemove().add(emptyUpdatedAttr);
+        }
+
+        populate(updatedAttrs, originalAttrs, result);
+
+        // 3. derived attributes
+        updatedAttrs = updated.getDerAttrMap();
+        originalAttrs = original.getDerAttrMap();
+
+        originalAttrNames = new HashSet<>(originalAttrs.keySet());
+        originalAttrNames.removeAll(updatedAttrs.keySet());
+
+        if (!incremental) {
+            result.getDerAttrsToRemove().clear();
+            result.getDerAttrsToRemove().addAll(originalAttrNames);
+        }
+
+        Set<String> updatedAttrNames = new HashSet<>(updatedAttrs.keySet());
+        updatedAttrNames.removeAll(originalAttrs.keySet());
+        result.getDerAttrsToAdd().clear();
+        result.getDerAttrsToAdd().addAll(updatedAttrNames);
+
+        // 4. virtual attributes
+        updatedAttrs = updated.getVirAttrMap();
+        originalAttrs = original.getVirAttrMap();
+
+        originalAttrNames = new HashSet<>(originalAttrs.keySet());
+        originalAttrNames.removeAll(updatedAttrs.keySet());
+
+        if (!incremental) {
+            result.getVirAttrsToRemove().clear();
+            result.getVirAttrsToRemove().addAll(originalAttrNames);
+        }
+
+        populate(updatedAttrs, originalAttrs, result, true);
+
+        // 5. resources
+        Set<String> updatedRes = new HashSet<>(updated.getResources());
+        Set<String> originalRes = new HashSet<>(original.getResources());
+
+        updatedRes.removeAll(originalRes);
+        result.getResourcesToAdd().clear();
+        result.getResourcesToAdd().addAll(updatedRes);
+
+        originalRes.removeAll(updated.getResources());
+
+        if (!incremental) {
+            result.getResourcesToRemove().clear();
+            result.getResourcesToRemove().addAll(originalRes);
+        }
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated UserTO
+     * @param original original UserTO
+     * @return UserMod containing differences
+     */
+    public static UserMod diff(final UserTO updated, final UserTO original) {
+        return diff(updated, original, false);
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated UserTO
+     * @param original original UserTO
+     * @param incremental perform incremental diff (without removing existing info)
+     * @return UserMod containing differences
+     */
+    public static UserMod diff(final UserTO updated, final UserTO original, final boolean incremental) {
+        UserMod result = new UserMod();
+
+        diff(updated, original, result, incremental);
+
+        // 0. realm
+        if (updated.getRealm() != null && (original.getRealm() == null
+                || !original.getRealm().equals(updated.getRealm()))) {
+
+            result.setRealm(updated.getRealm());
+        }
+
+        // 1. password
+        if (updated.getPassword() != null && (original.getPassword() == null
+                || !original.getPassword().equals(updated.getPassword()))) {
+
+            result.setPassword(updated.getPassword());
+        }
+
+        // 2. username
+        if (original.getUsername() != null && !original.getUsername().equals(updated.getUsername())) {
+            result.setUsername(updated.getUsername());
+        }
+
+        // 3. security question / answer
+        if (updated.getSecurityQuestion() == null) {
+            result.setSecurityQuestion(null);
+            result.setSecurityAnswer(null);
+        } else if (!updated.getSecurityQuestion().equals(original.getSecurityQuestion())
+                || StringUtils.isNotBlank(updated.getSecurityAnswer())) {
+
+            result.setSecurityQuestion(updated.getSecurityQuestion());
+            result.setSecurityAnswer(updated.getSecurityAnswer());
+        }
+
+        // 4. roles
+        result.getRolesToRemove().addAll(CollectionUtils.subtract(original.getRoles(), updated.getRoles()));
+        result.getRolesToAdd().addAll(CollectionUtils.subtract(updated.getRoles(), original.getRoles()));
+
+        return result;
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated GroupTO
+     * @param original original GroupTO
+     * @return GroupMod containing differences
+     */
+    public static GroupMod diff(final GroupTO updated, final GroupTO original) {
+        return diff(updated, original, false);
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated GroupTO
+     * @param original original GroupTO
+     * @param incremental perform incremental diff (without removing existing info)
+     * @return GroupMod containing differences
+     */
+    public static GroupMod diff(final GroupTO updated, final GroupTO original, final boolean incremental) {
+        GroupMod result = new GroupMod();
+
+        diff(updated, original, result, incremental);
+
+        // 1. name
+        if (!original.getName().equals(updated.getName())) {
+            result.setName(updated.getName());
+        }
+
+        // 2. owner
+        result.setUserOwner(new ReferenceMod(updated.getUserOwner()));
+        result.setGroupOwner(new ReferenceMod(updated.getGroupOwner()));
+
+        // 3. dynMembershipCond
+        result.setADynMembershipCond(updated.getADynMembershipCond());
+        result.setUDynMembershipCond(updated.getUDynMembershipCond());
+
+        return result;
+    }
+
+    private static List<AttrTO> getUpdateValues(final Map<String, AttrTO> attrs,
+            final Set<String> attrsToBeRemoved, final Set<AttrMod> attrsToBeUpdated) {
+
+        Map<String, AttrTO> rwattrs = new HashMap<>(attrs);
+        for (String attrName : attrsToBeRemoved) {
+            rwattrs.remove(attrName);
+        }
+        for (AttrMod attrMod : attrsToBeUpdated) {
+            if (rwattrs.containsKey(attrMod.getSchema())) {
+                AttrTO attrTO = rwattrs.get(attrMod.getSchema());
+                attrTO.getValues().removeAll(attrMod.getValuesToBeRemoved());
+                attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
+            } else {
+                AttrTO attrTO = new AttrTO();
+                attrTO.setSchema(attrMod.getSchema());
+                attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
+
+                rwattrs.put(attrMod.getSchema(), attrTO);
+            }
+        }
+
+        return new ArrayList<>(rwattrs.values());
+    }
+
+    private static <T extends AnyTO, K extends AnyMod> void apply(final T to,
+            final K mod, final T result) {
+
+        // 1. attributes
+        result.getPlainAttrs().addAll(getUpdateValues(to.getPlainAttrMap(),
+                mod.getPlainAttrsToRemove(), mod.getPlainAttrsToUpdate()));
+
+        // 2. derived attributes
+        Map<String, AttrTO> attrs = to.getDerAttrMap();
+        for (String attrName : mod.getDerAttrsToRemove()) {
+            attrs.remove(attrName);
+        }
+        for (String attrName : mod.getDerAttrsToAdd()) {
+            AttrTO attrTO = new AttrTO();
+            attrTO.setSchema(attrName);
+
+            attrs.put(attrName, attrTO);
+        }
+        result.getDerAttrs().addAll(attrs.values());
+
+        // 3. virtual attributes
+        result.getVirAttrs().addAll(getUpdateValues(to.getVirAttrMap(),
+                mod.getVirAttrsToRemove(), mod.getVirAttrsToUpdate()));
+
+        // 4. resources
+        result.getResources().removeAll(mod.getResourcesToRemove());
+        result.getResources().addAll(mod.getResourcesToAdd());
+    }
+
+    public static UserTO apply(final UserTO userTO, final UserMod userMod) {
+        // 1. check same id
+        if (userTO.getKey() != userMod.getKey()) {
+            throw new IllegalArgumentException("UserTO and UserMod ids must be the same");
+        }
+
+        UserTO result = SerializationUtils.clone(userTO);
+        apply(userTO, userMod, result);
+
+        // 0. realm
+        if (userMod.getRealm() != null) {
+            result.setRealm(userMod.getRealm());
+        }
+
+        // 1. password
+        result.setPassword(userMod.getPassword());
+
+        // 2. username
+        if (userMod.getUsername() != null) {
+            result.setUsername(userMod.getUsername());
+        }
+
+        // 3. roles
+        result.getRoles().removeAll(userMod.getRolesToRemove());
+        result.getRoles().addAll(userMod.getRolesToAdd());
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
deleted file mode 100644
index 6c250ef..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
+++ /dev/null
@@ -1,509 +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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
-import org.apache.syncope.common.lib.mod.ReferenceMod;
-import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-
-/**
- * Utility class for manipulating classes extending AbstractAttributableTO and AbstractAttributableMod.
- *
- * @see AbstractAttributableTO
- * @see AbstractAttributableMod
- */
-public final class AttributableOperations {
-
-    private AttributableOperations() {
-        // empty constructor for static utility classes
-    }
-
-    private static void populate(final Map<String, AttrTO> updatedAttrs,
-            final Map<String, AttrTO> originalAttrs, final AbstractAttributableMod result) {
-
-        populate(updatedAttrs, originalAttrs, result, false);
-    }
-
-    private static void populate(final Map<String, AttrTO> updatedAttrs,
-            final Map<String, AttrTO> originalAttrs, final AbstractAttributableMod result,
-            final boolean virtuals) {
-
-        for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
-            AttrMod mod = new AttrMod();
-            mod.setSchema(entry.getKey());
-
-            Set<String> updatedValues = new HashSet<>(entry.getValue().getValues());
-
-            Set<String> originalValues = originalAttrs.containsKey(entry.getKey())
-                    ? new HashSet<>(originalAttrs.get(entry.getKey()).getValues())
-                    : Collections.<String>emptySet();
-
-            if (!originalAttrs.containsKey(entry.getKey())) {
-                // SYNCOPE-459: take care of user virtual attributes without any value
-                updatedValues.remove("");
-                mod.getValuesToBeAdded().addAll(new ArrayList<>(updatedValues));
-
-                if (virtuals) {
-                    result.getVirAttrsToUpdate().add(mod);
-                } else {
-                    result.getPlainAttrsToUpdate().add(mod);
-                }
-            } else if (!updatedValues.equals(originalValues)) {
-                // avoid unwanted inputs
-                updatedValues.remove("");
-                if (!entry.getValue().isReadonly()) {
-                    mod.getValuesToBeAdded().addAll(updatedValues);
-
-                    if (!mod.isEmpty()) {
-                        if (virtuals) {
-                            result.getVirAttrsToRemove().add(mod.getSchema());
-                        } else {
-                            result.getPlainAttrsToRemove().add(mod.getSchema());
-                        }
-                    }
-                }
-
-                mod.getValuesToBeRemoved().addAll(originalValues);
-
-                if (!mod.isEmpty()) {
-                    if (virtuals) {
-                        result.getVirAttrsToUpdate().add(mod);
-                    } else {
-                        result.getPlainAttrsToUpdate().add(mod);
-                    }
-                }
-            }
-        }
-    }
-
-    private static void diff(
-            final AbstractAttributableTO updated,
-            final AbstractAttributableTO original,
-            final AbstractAttributableMod result,
-            final boolean incremental) {
-
-        // 1. check same id
-        if (updated.getKey() != original.getKey()) {
-            throw new IllegalArgumentException("AttributableTO's id must be the same");
-        }
-        result.setKey(updated.getKey());
-
-        // 2. attributes
-        Map<String, AttrTO> updatedAttrs = new HashMap<>(updated.getPlainAttrMap());
-        Map<String, AttrTO> originalAttrs = new HashMap<>(original.getPlainAttrMap());
-
-        Set<String> originalAttrNames = new HashSet<>(originalAttrs.keySet());
-        originalAttrNames.removeAll(updatedAttrs.keySet());
-
-        if (!incremental) {
-            result.getPlainAttrsToRemove().clear();
-            result.getPlainAttrsToRemove().addAll(originalAttrNames);
-        }
-
-        Set<String> emptyUpdatedAttrs = new HashSet<>();
-        for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
-            if (entry.getValue().getValues() == null || entry.getValue().getValues().isEmpty()) {
-
-                emptyUpdatedAttrs.add(entry.getKey());
-            }
-        }
-        for (String emptyUpdatedAttr : emptyUpdatedAttrs) {
-            updatedAttrs.remove(emptyUpdatedAttr);
-            result.getPlainAttrsToRemove().add(emptyUpdatedAttr);
-        }
-
-        populate(updatedAttrs, originalAttrs, result);
-
-        // 3. derived attributes
-        updatedAttrs = updated.getDerAttrMap();
-        originalAttrs = original.getDerAttrMap();
-
-        originalAttrNames = new HashSet<>(originalAttrs.keySet());
-        originalAttrNames.removeAll(updatedAttrs.keySet());
-
-        if (!incremental) {
-            result.getDerAttrsToRemove().clear();
-            result.getDerAttrsToRemove().addAll(originalAttrNames);
-        }
-
-        Set<String> updatedAttrNames = new HashSet<>(updatedAttrs.keySet());
-        updatedAttrNames.removeAll(originalAttrs.keySet());
-        result.getDerAttrsToAdd().clear();
-        result.getDerAttrsToAdd().addAll(updatedAttrNames);
-
-        // 4. virtual attributes
-        updatedAttrs = updated.getVirAttrMap();
-        originalAttrs = original.getVirAttrMap();
-
-        originalAttrNames = new HashSet<>(originalAttrs.keySet());
-        originalAttrNames.removeAll(updatedAttrs.keySet());
-
-        if (!incremental) {
-            result.getVirAttrsToRemove().clear();
-            result.getVirAttrsToRemove().addAll(originalAttrNames);
-        }
-
-        populate(updatedAttrs, originalAttrs, result, true);
-
-        // 5. resources
-        if (original instanceof AbstractSubjectTO && updated instanceof AbstractSubjectTO
-                && result instanceof AbstractSubjectMod) {
-
-            Set<String> updatedRes = new HashSet<>(((AbstractSubjectTO) updated).getResources());
-            Set<String> originalRes = new HashSet<>(((AbstractSubjectTO) original).getResources());
-
-            updatedRes.removeAll(originalRes);
-            ((AbstractSubjectMod) result).getResourcesToAdd().clear();
-            ((AbstractSubjectMod) result).getResourcesToAdd().addAll(updatedRes);
-
-            originalRes.removeAll(((AbstractSubjectTO) updated).getResources());
-
-            if (!incremental) {
-                ((AbstractSubjectMod) result).getResourcesToRemove().clear();
-                ((AbstractSubjectMod) result).getResourcesToRemove().addAll(originalRes);
-            }
-        }
-    }
-
-    /**
-     * Calculate modifications needed by first in order to be equal to second.
-     *
-     * @param updated updated UserTO
-     * @param original original UserTO
-     * @return UserMod containing differences
-     */
-    public static UserMod diff(final UserTO updated, final UserTO original) {
-        return diff(updated, original, false);
-    }
-
-    /**
-     * Calculate modifications needed by first in order to be equal to second.
-     *
-     * @param updated updated UserTO
-     * @param original original UserTO
-     * @param incremental perform incremental diff (without removing existing info)
-     * @return UserMod containing differences
-     */
-    public static UserMod diff(final UserTO updated, final UserTO original, final boolean incremental) {
-        UserMod result = new UserMod();
-
-        diff(updated, original, result, incremental);
-
-        // 0. realm
-        if (updated.getRealm() != null && (original.getRealm() == null
-                || !original.getRealm().equals(updated.getRealm()))) {
-
-            result.setRealm(updated.getRealm());
-        }
-
-        // 1. password
-        if (updated.getPassword() != null && (original.getPassword() == null
-                || !original.getPassword().equals(updated.getPassword()))) {
-
-            result.setPassword(updated.getPassword());
-        }
-
-        // 2. username
-        if (original.getUsername() != null && !original.getUsername().equals(updated.getUsername())) {
-            result.setUsername(updated.getUsername());
-        }
-
-        // 3. security question / answer
-        if (updated.getSecurityQuestion() == null) {
-            result.setSecurityQuestion(null);
-            result.setSecurityAnswer(null);
-        } else if (!updated.getSecurityQuestion().equals(original.getSecurityQuestion())
-                || StringUtils.isNotBlank(updated.getSecurityAnswer())) {
-
-            result.setSecurityQuestion(updated.getSecurityQuestion());
-            result.setSecurityAnswer(updated.getSecurityAnswer());
-        }
-
-        // 4. roles
-        result.getRolesToRemove().addAll(CollectionUtils.subtract(original.getRoles(), updated.getRoles()));
-        result.getRolesToAdd().addAll(CollectionUtils.subtract(updated.getRoles(), original.getRoles()));
-
-        // 5. memberships
-        Map<Long, MembershipTO> updatedMembs = updated.getMembershipMap();
-        Map<Long, MembershipTO> originalMembs = original.getMembershipMap();
-
-        for (Map.Entry<Long, MembershipTO> entry : updatedMembs.entrySet()) {
-            MembershipMod membMod = new MembershipMod();
-            membMod.setGroup(entry.getValue().getGroupKey());
-
-            if (originalMembs.containsKey(entry.getKey())) {
-                // if memberships are actually same, just make the isEmpty() call below succeed
-                if (entry.getValue().equals(originalMembs.get(entry.getKey()))) {
-                    membMod.setGroup(0);
-                } else {
-                    diff(entry.getValue(), originalMembs.get(entry.getKey()), membMod, false);
-                }
-            } else {
-                for (AttrTO attr : entry.getValue().getPlainAttrs()) {
-                    AttrMod attrMod = new AttrMod();
-                    attrMod.setSchema(attr.getSchema());
-                    attrMod.getValuesToBeAdded().addAll(attr.getValues());
-
-                    if (!attrMod.isEmpty()) {
-                        membMod.getPlainAttrsToUpdate().add(attrMod);
-                        membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
-                    }
-                }
-                for (AttrTO attr : entry.getValue().getDerAttrs()) {
-                    membMod.getDerAttrsToAdd().add(attr.getSchema());
-                }
-                for (AttrTO attr : entry.getValue().getVirAttrs()) {
-                    AttrMod attrMod = new AttrMod();
-                    attrMod.setSchema(attr.getSchema());
-                    attrMod.getValuesToBeAdded().addAll(attr.getValues());
-
-                    if (!attrMod.isEmpty()) {
-                        membMod.getVirAttrsToUpdate().add(attrMod);
-                        membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
-                    }
-                }
-            }
-
-            if (!membMod.isEmpty()) {
-                result.getMembershipsToAdd().add(membMod);
-            }
-        }
-
-        if (!incremental) {
-            Set<Long> originalGroups = new HashSet<>(originalMembs.keySet());
-            originalGroups.removeAll(updatedMembs.keySet());
-            for (Long groupId : originalGroups) {
-                result.getMembershipsToRemove().add(originalMembs.get(groupId).getKey());
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Calculate modifications needed by first in order to be equal to second.
-     *
-     * @param updated updated GroupTO
-     * @param original original GroupTO
-     * @return GroupMod containing differences
-     */
-    public static GroupMod diff(final GroupTO updated, final GroupTO original) {
-        return diff(updated, original, false);
-    }
-
-    /**
-     * Calculate modifications needed by first in order to be equal to second.
-     *
-     * @param updated updated GroupTO
-     * @param original original GroupTO
-     * @param incremental perform incremental diff (without removing existing info)
-     * @return GroupMod containing differences
-     */
-    public static GroupMod diff(final GroupTO updated, final GroupTO original, final boolean incremental) {
-        GroupMod result = new GroupMod();
-
-        diff(updated, original, result, incremental);
-
-        // 1. name
-        if (!original.getName().equals(updated.getName())) {
-            result.setName(updated.getName());
-        }
-
-        // 2. templates
-        Set<String> updatedTemplates = new HashSet<>(updated.getGPlainAttrTemplates());
-        Set<String> originalTemplates = new HashSet<>(original.getGPlainAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModGAttrTemplates(false);
-            result.getGPlainAttrTemplates().clear();
-        } else {
-            result.setModGAttrTemplates(true);
-            result.getGPlainAttrTemplates().addAll(updated.getGPlainAttrTemplates());
-        }
-        updatedTemplates = new HashSet<>(updated.getGDerAttrTemplates());
-        originalTemplates = new HashSet<>(original.getGDerAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModGDerAttrTemplates(false);
-            result.getGDerAttrTemplates().clear();
-        } else {
-            result.setModGDerAttrTemplates(true);
-            result.getGDerAttrTemplates().addAll(updated.getGDerAttrTemplates());
-        }
-        updatedTemplates = new HashSet<>(updated.getGVirAttrTemplates());
-        originalTemplates = new HashSet<>(original.getGVirAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModGVirAttrTemplates(false);
-            result.getGVirAttrTemplates().clear();
-        } else {
-            result.setModGVirAttrTemplates(true);
-            result.getGVirAttrTemplates().addAll(updated.getGVirAttrTemplates());
-        }
-        updatedTemplates = new HashSet<>(updated.getMPlainAttrTemplates());
-        originalTemplates = new HashSet<>(original.getMPlainAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModMAttrTemplates(false);
-            result.getMPlainAttrTemplates().clear();
-        } else {
-            result.setModMAttrTemplates(true);
-            result.getMPlainAttrTemplates().addAll(updated.getMPlainAttrTemplates());
-        }
-        updatedTemplates = new HashSet<>(updated.getMDerAttrTemplates());
-        originalTemplates = new HashSet<>(original.getMDerAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModMDerAttrTemplates(false);
-            result.getMDerAttrTemplates().clear();
-        } else {
-            result.setModMDerAttrTemplates(true);
-            result.getMDerAttrTemplates().addAll(updated.getMDerAttrTemplates());
-        }
-        updatedTemplates = new HashSet<>(updated.getMVirAttrTemplates());
-        originalTemplates = new HashSet<>(original.getMVirAttrTemplates());
-        if (updatedTemplates.equals(originalTemplates)) {
-            result.setModMVirAttrTemplates(false);
-            result.getMVirAttrTemplates().clear();
-        } else {
-            result.setModMVirAttrTemplates(true);
-            result.getMVirAttrTemplates().addAll(updated.getMVirAttrTemplates());
-        }
-
-        // 3. owner
-        result.setUserOwner(new ReferenceMod(updated.getUserOwner()));
-        result.setGroupOwner(new ReferenceMod(updated.getGroupOwner()));
-
-        // 4. dynMembershipCond
-        result.setDynMembershipCond(updated.getDynMembershipCond());
-
-        return result;
-    }
-
-    private static List<AttrTO> getUpdateValues(final Map<String, AttrTO> attrs,
-            final Set<String> attrsToBeRemoved, final Set<AttrMod> attrsToBeUpdated) {
-
-        Map<String, AttrTO> rwattrs = new HashMap<>(attrs);
-        for (String attrName : attrsToBeRemoved) {
-            rwattrs.remove(attrName);
-        }
-        for (AttrMod attrMod : attrsToBeUpdated) {
-            if (rwattrs.containsKey(attrMod.getSchema())) {
-                AttrTO attrTO = rwattrs.get(attrMod.getSchema());
-                attrTO.getValues().removeAll(attrMod.getValuesToBeRemoved());
-                attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
-            } else {
-                AttrTO attrTO = new AttrTO();
-                attrTO.setSchema(attrMod.getSchema());
-                attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
-
-                rwattrs.put(attrMod.getSchema(), attrTO);
-            }
-        }
-
-        return new ArrayList<>(rwattrs.values());
-    }
-
-    private static <T extends AbstractAttributableTO, K extends AbstractAttributableMod> void apply(final T to,
-            final K mod, final T result) {
-
-        // 1. attributes
-        result.getPlainAttrs().addAll(getUpdateValues(to.getPlainAttrMap(),
-                mod.getPlainAttrsToRemove(), mod.getPlainAttrsToUpdate()));
-
-        // 2. derived attributes
-        Map<String, AttrTO> attrs = to.getDerAttrMap();
-        for (String attrName : mod.getDerAttrsToRemove()) {
-            attrs.remove(attrName);
-        }
-        for (String attrName : mod.getDerAttrsToAdd()) {
-            AttrTO attrTO = new AttrTO();
-            attrTO.setSchema(attrName);
-
-            attrs.put(attrName, attrTO);
-        }
-        result.getDerAttrs().addAll(attrs.values());
-
-        // 3. virtual attributes
-        result.getVirAttrs().addAll(getUpdateValues(to.getVirAttrMap(),
-                mod.getVirAttrsToRemove(), mod.getVirAttrsToUpdate()));
-
-        // 4. resources
-        if (result instanceof AbstractSubjectTO && mod instanceof AbstractSubjectMod) {
-            ((AbstractSubjectTO) result).getResources().removeAll(((AbstractSubjectMod) mod).getResourcesToRemove());
-            ((AbstractSubjectTO) result).getResources().addAll(((AbstractSubjectMod) mod).getResourcesToAdd());
-        }
-    }
-
-    public static UserTO apply(final UserTO userTO, final UserMod userMod) {
-        // 1. check same id
-        if (userTO.getKey() != userMod.getKey()) {
-            throw new IllegalArgumentException("UserTO and UserMod ids must be the same");
-        }
-
-        UserTO result = SerializationUtils.clone(userTO);
-        apply(userTO, userMod, result);
-
-        // 0. realm
-        if (userMod.getRealm() != null) {
-            result.setRealm(userMod.getRealm());
-        }
-
-        // 1. password
-        result.setPassword(userMod.getPassword());
-
-        // 2. username
-        if (userMod.getUsername() != null) {
-            result.setUsername(userMod.getUsername());
-        }
-
-        // 3. roles
-        result.getRoles().removeAll(userMod.getRolesToRemove());
-        result.getRoles().addAll(userMod.getRolesToAdd());
-
-        // 4. memberships
-        Map<Long, MembershipTO> membs = result.getMembershipMap();
-        for (Long membKey : userMod.getMembershipsToRemove()) {
-            result.getMemberships().remove(membs.get(membKey));
-        }
-        for (MembershipMod membMod : userMod.getMembershipsToAdd()) {
-            MembershipTO membTO = new MembershipTO();
-            membTO.setGroupKey(membMod.getGroup());
-
-            apply(membTO, membMod, membTO);
-        }
-
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/CollectionUtils2.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/CollectionUtils2.java b/common/lib/src/main/java/org/apache/syncope/common/lib/CollectionUtils2.java
deleted file mode 100644
index 69739b6..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/CollectionUtils2.java
+++ /dev/null
@@ -1,153 +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;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.SetUtils;
-import org.apache.commons.collections4.Transformer;
-
-public final class CollectionUtils2 {
-
-    /**
-     * Returns the next element in <tt>iterator</tt> or <tt>defaultValue</tt> if the iterator is empty.
-     *
-     * @param defaultValue the default value to return if the iterator is empty
-     * @return the next element of <tt>iterator</tt> or the default value
-     */
-    public static <T> T getNext(final Iterator<? extends T> iterator, final T defaultValue) {
-        return iterator.hasNext() ? iterator.next() : defaultValue;
-    }
-
-    /**
-     * Returns the first element in <tt>iterable</tt> or <tt>defaultValue</tt> if the iterable is empty.
-     *
-     * <p/>
-     * If no default value is desired (and the caller instead wants a {@link java.util.NoSuchElementException} to be
-     * thrown), it is recommended that <tt>iterable.iterator().next()}</tt> is used instead.
-     *
-     * @param defaultValue the default value to return if the iterable is empty
-     * @return the first element of <tt>iterable</tt> or the default value
-     */
-    public static <T> T getFirst(final Iterable<? extends T> iterable, final T defaultValue) {
-        return getNext(iterable.iterator(), defaultValue);
-    }
-
-    /**
-     * Returns the first element in <tt>iterable</tt> or <tt>null</tt> if the iterable is empty.
-     *
-     * @return the first element of <tt>iterable</tt> or <tt>null</tt>
-     */
-    public static <T> T getFirstOrNull(final Iterable<? extends T> iterable) {
-        return getNext(iterable.iterator(), null);
-    }
-
-    /**
-     * Transforms all elements from inputCollection with the given transformer
-     * and adds them to the outputCollection if the provided predicate is verified.
-     * <p/>
-     * If the input collection or transformer is null, there is no change to the
-     * output collection.
-     *
-     * @param <I> the type of object in the input collection
-     * @param <O> the type of object in the output collection
-     * @param <R> the output type of the transformer - this extends O.
-     * @param inputCollection the collection to get the input from, may be null
-     * @param transformer the transformer to use, may be null
-     * @param predicate the predicate to use, may be null
-     * @param outputCollection the collection to output into, may not be null if the inputCollection
-     * and transformer are not null
-     * @return the outputCollection with the transformed input added
-     * @throws NullPointerException if the output collection is null and both, inputCollection and
-     * transformer are not null
-     */
-    public static <I, O, R extends Collection<? super O>> R collect(final Iterable<? extends I> inputCollection,
-            final Transformer<? super I, ? extends O> transformer, final Predicate<? super I> predicate,
-            final R outputCollection) {
-
-        if (inputCollection != null) {
-            return collect(inputCollection.iterator(), transformer, predicate, outputCollection);
-        }
-        return outputCollection;
-    }
-
-    /**
-     * Transforms all elements from the inputIterator with the given transformer
-     * and adds them to the outputCollection.
-     * <p/>
-     * If the input iterator or transformer is null, there is no change to the
-     * output collection.
-     *
-     * @param inputIterator the iterator to get the input from, may be null
-     * @param transformer the transformer to use, may be null
-     * @param predicate the predicate to use, may be null
-     * @param outputCollection the collection to output into, may not be null if the inputCollection
-     * and transformer are not null
-     * @param <I> the type of object in the input collection
-     * @param <O> the type of object in the output collection
-     * @param <R> the output type of the transformer - this extends O.
-     * @return the outputCollection with the transformed input added
-     * @throws NullPointerException if the output collection is null and both, inputCollection and
-     * transformer are not null
-     */
-    public static <I, O, R extends Collection<? super O>> R collect(final Iterator<? extends I> inputIterator,
-            final Transformer<? super I, ? extends O> transformer, final Predicate<? super I> predicate,
-            final R outputCollection) {
-
-        if (inputIterator != null && transformer != null) {
-            while (inputIterator.hasNext()) {
-                final I item = inputIterator.next();
-                final O value = transformer.transform(item);
-                if (predicate == null || predicate.evaluate(item)) {
-                    outputCollection.add(value);
-                }
-            }
-        }
-        return outputCollection;
-    }
-
-    /**
-     * Gets elements in the input collection that match the predicate.
-     * <p/>
-     * A <code>null</code> collection or predicate matches no elements.
-     *
-     * @param <C> the type of object the {@link Iterable} contains
-     * @param input the {@link Iterable} to get the input from, may be null
-     * @param predicate the predicate to use, may be null
-     * @return the matches for the predicate in the collection
-     */
-    public static <C> Collection<C> find(final Iterable<C> input, final Predicate<? super C> predicate) {
-        Set<C> result = SetUtils.predicatedSet(new HashSet<C>(), predicate);
-        if (input != null && predicate != null) {
-            for (final C o : input) {
-                if (predicate.evaluate(o)) {
-                    result.add(o);
-                }
-            }
-        }
-        return SetUtils.unmodifiableSet(result);
-    }
-
-    private CollectionUtils2() {
-        // private constructor for static utility class
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
deleted file mode 100644
index aa5d442..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
+++ /dev/null
@@ -1,111 +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.mod;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.HashSet;
-import java.util.Set;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-/**
- * Abstract base class for objects that can have attributes removed, added or updated.
- *
- * Attributes can be regular attributes, derived attributes, virtual attributes and resources.
- */
-@XmlType
-public abstract class AbstractAttributableMod extends AbstractBaseBean {
-
-    private static final long serialVersionUID = 3241118574016303198L;
-
-    protected long key;
-
-    protected final Set<AttrMod> plainAttrsToUpdate = new HashSet<>();
-
-    protected final Set<String> plainAttrsToRemove = new HashSet<>();
-
-    protected final Set<String> derAttrsToAdd = new HashSet<>();
-
-    protected final Set<String> derAttrsToRemove = new HashSet<>();
-
-    protected final Set<AttrMod> virAttrsToUpdate = new HashSet<>();
-
-    protected final Set<String> virAttrsToRemove = new HashSet<>();
-
-    public long getKey() {
-        return key;
-    }
-
-    public void setKey(final long key) {
-        this.key = key;
-    }
-
-    @XmlElementWrapper(name = "plainAttrsToRemove")
-    @XmlElement(name = "attribute")
-    @JsonProperty("plainAttrsToRemove")
-    public Set<String> getPlainAttrsToRemove() {
-        return plainAttrsToRemove;
-    }
-
-    @XmlElementWrapper(name = "plainAttrsToUpdate")
-    @XmlElement(name = "attributeMod")
-    @JsonProperty("plainAttrsToUpdate")
-    public Set<AttrMod> getPlainAttrsToUpdate() {
-        return plainAttrsToUpdate;
-    }
-
-    @XmlElementWrapper(name = "derAttrsToAdd")
-    @XmlElement(name = "attribute")
-    @JsonProperty("derAttrsToAdd")
-    public Set<String> getDerAttrsToAdd() {
-        return derAttrsToAdd;
-    }
-
-    @XmlElementWrapper(name = "derAttrsToRemove")
-    @XmlElement(name = "attribute")
-    @JsonProperty("derAttrsToRemove")
-    public Set<String> getDerAttrsToRemove() {
-        return derAttrsToRemove;
-    }
-
-    @XmlElementWrapper(name = "virAttrsToRemove")
-    @XmlElement(name = "attribute")
-    @JsonProperty("virAttrsToRemove")
-    public Set<String> getVirAttrsToRemove() {
-        return virAttrsToRemove;
-    }
-
-    @XmlElementWrapper(name = "virAttrsToUpdate")
-    @XmlElement(name = "attribute")
-    @JsonProperty("virAttrsToUpdate")
-    public Set<AttrMod> getVirAttrsToUpdate() {
-        return virAttrsToUpdate;
-    }
-
-    /**
-     * @return true is all backing Sets are empty.
-     */
-    public boolean isEmpty() {
-        return plainAttrsToUpdate.isEmpty() && plainAttrsToRemove.isEmpty()
-                && derAttrsToAdd.isEmpty() && derAttrsToRemove.isEmpty()
-                && virAttrsToUpdate.isEmpty() && virAttrsToRemove.isEmpty();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
deleted file mode 100644
index 3671785..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.mod;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.HashSet;
-import java.util.Set;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlType
-public abstract class AbstractSubjectMod extends AbstractAttributableMod {
-
-    private static final long serialVersionUID = -6404459635536484024L;
-
-    private String realm;
-
-    protected final Set<String> resourcesToAdd = new HashSet<>();
-
-    protected final Set<String> resourcesToRemove = new HashSet<>();
-
-    public String getRealm() {
-        return realm;
-    }
-
-    public void setRealm(final String realm) {
-        this.realm = realm;
-    }
-
-    @XmlElementWrapper(name = "resourcesToAdd")
-    @XmlElement(name = "resource")
-    @JsonProperty("resourcesToAdd")
-    public Set<String> getResourcesToAdd() {
-        return resourcesToAdd;
-    }
-
-    @XmlElementWrapper(name = "resourcesToRemove")
-    @XmlElement(name = "resource")
-    @JsonProperty("resourcesToRemove")
-    public Set<String> getResourcesToRemove() {
-        return resourcesToRemove;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return super.isEmpty() && resourcesToAdd.isEmpty() && resourcesToRemove.isEmpty();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
new file mode 100644
index 0000000..ec508c9
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyMod.java
@@ -0,0 +1,135 @@
+/*
+ * 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.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlType
+public abstract class AnyMod extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 7366724481786360591L;
+
+    protected long key;
+
+    private String realm;
+
+    protected final Set<AttrMod> plainAttrsToUpdate = new HashSet<>();
+
+    protected final Set<String> plainAttrsToRemove = new HashSet<>();
+
+    protected final Set<String> derAttrsToAdd = new HashSet<>();
+
+    protected final Set<String> derAttrsToRemove = new HashSet<>();
+
+    protected final Set<AttrMod> virAttrsToUpdate = new HashSet<>();
+
+    protected final Set<String> virAttrsToRemove = new HashSet<>();
+
+    protected final Set<String> resourcesToAdd = new HashSet<>();
+
+    protected final Set<String> resourcesToRemove = new HashSet<>();
+
+    public long getKey() {
+        return key;
+    }
+
+    public void setKey(final long key) {
+        this.key = key;
+    }
+
+    public String getRealm() {
+        return realm;
+    }
+
+    public void setRealm(final String realm) {
+        this.realm = realm;
+    }
+
+    @XmlElementWrapper(name = "plainAttrsToRemove")
+    @XmlElement(name = "attribute")
+    @JsonProperty("plainAttrsToRemove")
+    public Set<String> getPlainAttrsToRemove() {
+        return plainAttrsToRemove;
+    }
+
+    @XmlElementWrapper(name = "plainAttrsToUpdate")
+    @XmlElement(name = "attributeMod")
+    @JsonProperty("plainAttrsToUpdate")
+    public Set<AttrMod> getPlainAttrsToUpdate() {
+        return plainAttrsToUpdate;
+    }
+
+    @XmlElementWrapper(name = "derAttrsToAdd")
+    @XmlElement(name = "attribute")
+    @JsonProperty("derAttrsToAdd")
+    public Set<String> getDerAttrsToAdd() {
+        return derAttrsToAdd;
+    }
+
+    @XmlElementWrapper(name = "derAttrsToRemove")
+    @XmlElement(name = "attribute")
+    @JsonProperty("derAttrsToRemove")
+    public Set<String> getDerAttrsToRemove() {
+        return derAttrsToRemove;
+    }
+
+    @XmlElementWrapper(name = "virAttrsToRemove")
+    @XmlElement(name = "attribute")
+    @JsonProperty("virAttrsToRemove")
+    public Set<String> getVirAttrsToRemove() {
+        return virAttrsToRemove;
+    }
+
+    @XmlElementWrapper(name = "virAttrsToUpdate")
+    @XmlElement(name = "attribute")
+    @JsonProperty("virAttrsToUpdate")
+    public Set<AttrMod> getVirAttrsToUpdate() {
+        return virAttrsToUpdate;
+    }
+
+    @XmlElementWrapper(name = "resourcesToAdd")
+    @XmlElement(name = "resource")
+    @JsonProperty("resourcesToAdd")
+    public Set<String> getResourcesToAdd() {
+        return resourcesToAdd;
+    }
+
+    @XmlElementWrapper(name = "resourcesToRemove")
+    @XmlElement(name = "resource")
+    @JsonProperty("resourcesToRemove")
+    public Set<String> getResourcesToRemove() {
+        return resourcesToRemove;
+    }
+
+    /**
+     * @return true is all backing collections are empty.
+     */
+    public boolean isEmpty() {
+        return plainAttrsToUpdate.isEmpty() && plainAttrsToRemove.isEmpty()
+                && derAttrsToAdd.isEmpty() && derAttrsToRemove.isEmpty()
+                && virAttrsToUpdate.isEmpty() && virAttrsToRemove.isEmpty()
+                && resourcesToAdd.isEmpty() && resourcesToRemove.isEmpty();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyObjectMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyObjectMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyObjectMod.java
new file mode 100644
index 0000000..b51a67b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AnyObjectMod.java
@@ -0,0 +1,71 @@
+/*
+ * 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.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "anyObjectMod")
+@XmlType
+public class AnyObjectMod extends AnyMod {
+
+    private static final long serialVersionUID = -3474517624611170097L;
+
+    private final List<Long> relationshipsToAdd = new ArrayList<>();
+
+    private final List<Long> relationshipsToRemove = new ArrayList<>();
+
+    private final List<Long> membershipsToAdd = new ArrayList<>();
+
+    private final List<Long> membershipsToRemove = new ArrayList<>();
+
+    @XmlElementWrapper(name = "relationshipsToAdd")
+    @XmlElement(name = "relationship")
+    @JsonProperty("relationshipsToAdd")
+    public List<Long> getRelationshipsToAdd() {
+        return relationshipsToAdd;
+    }
+
+    @XmlElementWrapper(name = "urelationshipsToRemove")
+    @XmlElement(name = "urelationship")
+    @JsonProperty("urelationshipsToRemove")
+    public List<Long> getRelationshipsToRemove() {
+        return relationshipsToRemove;
+    }
+
+    @XmlElementWrapper(name = "membershipsToAdd")
+    @XmlElement(name = "membership")
+    @JsonProperty("membershipsToAdd")
+    public List<Long> getMembershipsToAdd() {
+        return membershipsToAdd;
+    }
+
+    @XmlElementWrapper(name = "membershipsToRemove")
+    @XmlElement(name = "membership")
+    @JsonProperty("membershipsToRemove")
+    public List<Long> getMembershipsToRemove() {
+        return membershipsToRemove;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/GroupMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/GroupMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/GroupMod.java
index 5620fa1..3c948ea 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/GroupMod.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/GroupMod.java
@@ -19,17 +19,12 @@
 package org.apache.syncope.common.lib.mod;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "groupMod")
 @XmlType
-public class GroupMod extends AbstractSubjectMod {
+public class GroupMod extends AnyMod {
 
     private static final long serialVersionUID = 7455805264680210747L;
 
@@ -39,31 +34,9 @@ public class GroupMod extends AbstractSubjectMod {
 
     private ReferenceMod groupOwner;
 
-    private boolean modGAttrTemplates;
+    private String aDynMembershipCond;
 
-    private final List<String> gPlainAttrTemplates = new ArrayList<>();
-
-    private boolean modGDerAttrTemplates;
-
-    private final List<String> gDerAttrTemplates = new ArrayList<>();
-
-    private boolean modGVirAttrTemplates;
-
-    private final List<String> gVirAttrTemplates = new ArrayList<>();
-
-    private boolean modMAttrTemplates;
-
-    private final List<String> mPlainAttrTemplates = new ArrayList<>();
-
-    private boolean modMDerAttrTemplates;
-
-    private final List<String> mDerAttrTemplates = new ArrayList<>();
-
-    private boolean modMVirAttrTemplates;
-
-    private final List<String> mVirAttrTemplates = new ArrayList<>();
-
-    private String dynMembershipCond;
+    private String uDynMembershipCond;
 
     public String getName() {
         return name;
@@ -89,110 +62,26 @@ public class GroupMod extends AbstractSubjectMod {
         this.groupOwner = groupOwner;
     }
 
-    public boolean isModGAttrTemplates() {
-        return modGAttrTemplates;
-    }
-
-    public void setModGAttrTemplates(final boolean modGAttrTemplates) {
-        this.modGAttrTemplates = modGAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "gPlainAttrTemplates")
-    @XmlElement(name = "gAttrTemplate")
-    @JsonProperty("gPlainAttrTemplates")
-    public List<String> getGPlainAttrTemplates() {
-        return gPlainAttrTemplates;
-    }
-
-    public boolean isModGDerAttrTemplates() {
-        return modGDerAttrTemplates;
-    }
-
-    public void setModGDerAttrTemplates(final boolean modGDerAttrTemplates) {
-        this.modGDerAttrTemplates = modGDerAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "gDerAttrTemplates")
-    @XmlElement(name = "gDerAttrTemplate")
-    @JsonProperty("gDerAttrTemplates")
-    public List<String> getGDerAttrTemplates() {
-        return gDerAttrTemplates;
-    }
-
-    public boolean isModGVirAttrTemplates() {
-        return modGVirAttrTemplates;
-    }
-
-    public void setModGVirAttrTemplates(final boolean modGVirAttrTemplates) {
-        this.modGVirAttrTemplates = modGVirAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "gVirAttrTemplates")
-    @XmlElement(name = "gVirAttrTemplate")
-    @JsonProperty("gVirAttrTemplates")
-    public List<String> getGVirAttrTemplates() {
-        return gVirAttrTemplates;
-    }
-
-    public boolean isModMAttrTemplates() {
-        return modMAttrTemplates;
-    }
-
-    public void setModMAttrTemplates(final boolean modMAttrTemplates) {
-        this.modMAttrTemplates = modMAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "mPlainAttrTemplates")
-    @XmlElement(name = "mAttrTemplate")
-    @JsonProperty("mPlainAttrTemplates")
-    public List<String> getMPlainAttrTemplates() {
-        return mPlainAttrTemplates;
-    }
-
-    public boolean isModMDerAttrTemplates() {
-        return modMDerAttrTemplates;
-    }
-
-    public void setModMDerAttrTemplates(final boolean modMDerAttrTemplates) {
-        this.modMDerAttrTemplates = modMDerAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "mDerAttrTemplates")
-    @XmlElement(name = "mDerAttrTemplate")
-    @JsonProperty("mDerAttrTemplates")
-    public List<String> getMDerAttrTemplates() {
-        return mDerAttrTemplates;
-    }
-
-    public boolean isModMVirAttrTemplates() {
-        return modMVirAttrTemplates;
-    }
-
-    public void setModMVirAttrTemplates(final boolean modMVirAttrTemplates) {
-        this.modMVirAttrTemplates = modMVirAttrTemplates;
+    public String getADynMembershipCond() {
+        return aDynMembershipCond;
     }
 
-    @XmlElementWrapper(name = "mVirAttrTemplates")
-    @XmlElement(name = "mVirAttrTemplate")
-    @JsonProperty("mVirAttrTemplates")
-    public List<String> getMVirAttrTemplates() {
-        return mVirAttrTemplates;
+    public void setADynMembershipCond(final String aDynMembershipCond) {
+        this.aDynMembershipCond = aDynMembershipCond;
     }
 
-    public String getDynMembershipCond() {
-        return dynMembershipCond;
+    public String getUDynMembershipCond() {
+        return uDynMembershipCond;
     }
 
-    public void setDynMembershipCond(final String dynMembershipCond) {
-        this.dynMembershipCond = dynMembershipCond;
+    public void setUDynMembershipCond(final String uDynMembershipCond) {
+        this.uDynMembershipCond = uDynMembershipCond;
     }
 
     @JsonIgnore
     @Override
     public boolean isEmpty() {
         return super.isEmpty() && name == null && userOwner == null && groupOwner == null
-                && gPlainAttrTemplates.isEmpty() && gDerAttrTemplates.isEmpty() && gVirAttrTemplates.isEmpty()
-                && mPlainAttrTemplates.isEmpty() && mDerAttrTemplates.isEmpty() && mVirAttrTemplates.isEmpty()
-                && dynMembershipCond == null;
+                && aDynMembershipCond == null && uDynMembershipCond == null;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
deleted file mode 100644
index d414011..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
+++ /dev/null
@@ -1,46 +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.mod;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement
-@XmlType
-public class MembershipMod extends AbstractAttributableMod {
-
-    private static final long serialVersionUID = 2511869129977331525L;
-
-    private long group;
-
-    public long getGroup() {
-        return group;
-    }
-
-    public void setGroup(final long group) {
-        this.group = group;
-    }
-
-    @JsonIgnore
-    @Override
-    public boolean isEmpty() {
-        return super.isEmpty() && group == 0;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
index fe63b63..fe09eeb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
@@ -20,7 +20,9 @@ package org.apache.syncope.common.lib.mod;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
@@ -29,7 +31,7 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "userMod")
 @XmlType
-public class UserMod extends AbstractSubjectMod {
+public class UserMod extends AnyMod {
 
     private static final long serialVersionUID = 3081848906558106204L;
 
@@ -37,13 +39,17 @@ public class UserMod extends AbstractSubjectMod {
 
     private String password;
 
-    private final Set<Long> rolesToAdd = new HashSet<>();
+    private final List<Long> relationshipsToAdd = new ArrayList<>();
 
-    private final Set<Long> rolesToRemove = new HashSet<>();
+    private final List<Long> relationshipsToRemove = new ArrayList<>();
+
+    private final List<Long> membershipsToAdd = new ArrayList<>();
+
+    private final List<Long> membershipsToRemove = new ArrayList<>();
 
-    private final Set<MembershipMod> membershipsToAdd = new HashSet<>();
+    private final Set<Long> rolesToAdd = new HashSet<>();
 
-    private final Set<Long> membershipsToRemove = new HashSet<>();
+    private final Set<Long> rolesToRemove = new HashSet<>();
 
     private StatusMod pwdPropRequest;
 
@@ -67,34 +73,48 @@ public class UserMod extends AbstractSubjectMod {
         this.password = password;
     }
 
-    @XmlElementWrapper(name = "rolesToAdd")
-    @XmlElement(name = "role")
-    @JsonProperty("rolesToAdd")
-    public Set<Long> getRolesToAdd() {
-        return rolesToAdd;
+    @XmlElementWrapper(name = "relationshipsToAdd")
+    @XmlElement(name = "relationship")
+    @JsonProperty("relationshipsToAdd")
+    public List<Long> getRelationshipsToAdd() {
+        return relationshipsToAdd;
     }
 
-    @XmlElementWrapper(name = "rolesToRemove")
-    @XmlElement(name = "role")
-    @JsonProperty("rolesToRemove")
-    public Set<Long> getRolesToRemove() {
-        return rolesToRemove;
+    @XmlElementWrapper(name = "urelationshipsToRemove")
+    @XmlElement(name = "urelationship")
+    @JsonProperty("urelationshipsToRemove")
+    public List<Long> getRelationshipsToRemove() {
+        return relationshipsToRemove;
     }
 
     @XmlElementWrapper(name = "membershipsToAdd")
     @XmlElement(name = "membership")
     @JsonProperty("membershipsToAdd")
-    public Set<MembershipMod> getMembershipsToAdd() {
+    public List<Long> getMembershipsToAdd() {
         return membershipsToAdd;
     }
 
     @XmlElementWrapper(name = "membershipsToRemove")
     @XmlElement(name = "membership")
     @JsonProperty("membershipsToRemove")
-    public Set<Long> getMembershipsToRemove() {
+    public List<Long> getMembershipsToRemove() {
         return membershipsToRemove;
     }
 
+    @XmlElementWrapper(name = "rolesToAdd")
+    @XmlElement(name = "role")
+    @JsonProperty("rolesToAdd")
+    public Set<Long> getRolesToAdd() {
+        return rolesToAdd;
+    }
+
+    @XmlElementWrapper(name = "rolesToRemove")
+    @XmlElement(name = "role")
+    @JsonProperty("rolesToRemove")
+    public Set<Long> getRolesToRemove() {
+        return rolesToRemove;
+    }
+
     public StatusMod getPwdPropRequest() {
         return pwdPropRequest;
     }
@@ -125,8 +145,6 @@ public class UserMod extends AbstractSubjectMod {
         return super.isEmpty()
                 && password == null
                 && username == null
-                && membershipsToAdd.isEmpty()
-                && membershipsToRemove.isEmpty()
                 && pwdPropRequest == null
                 && securityQuestion == null
                 && securityAnswer == null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractAnyReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractAnyReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractAnyReportletConf.java
new file mode 100644
index 0000000..e6949b6
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractAnyReportletConf.java
@@ -0,0 +1,84 @@
+/*
+ * 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.report;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.annotation.FormAttributeField;
+import org.apache.syncope.common.lib.types.IntMappingType;
+
+@XmlType
+public abstract class AbstractAnyReportletConf extends AbstractReportletConf {
+
+    private static final long serialVersionUID = -5388597116592877789L;
+
+    @FormAttributeField(userSearch = true)
+    protected String matchingCond;
+
+    @FormAttributeField(schema = IntMappingType.UserPlainSchema)
+    protected final List<String> plainAttrs = new ArrayList<>();
+
+    @FormAttributeField(schema = IntMappingType.UserDerivedSchema)
+    protected final List<String> derAttrs = new ArrayList<>();
+
+    @FormAttributeField(schema = IntMappingType.UserVirtualSchema)
+    protected final List<String> virAttrs = new ArrayList<>();
+
+    public AbstractAnyReportletConf() {
+        super();
+    }
+
+    public AbstractAnyReportletConf(final String name) {
+        super(name);
+    }
+
+    public String getMatchingCond() {
+        return matchingCond;
+    }
+
+    public void setMatchingCond(final String matchingCond) {
+        this.matchingCond = matchingCond;
+    }
+
+    @XmlElementWrapper(name = "plainAttrs")
+    @XmlElement(name = "attribute")
+    @JsonProperty("plainAttrs")
+    public List<String> getPlainAttrs() {
+        return plainAttrs;
+    }
+
+    @XmlElementWrapper(name = "derAttrs")
+    @XmlElement(name = "attribute")
+    @JsonProperty("derAttrs")
+    public List<String> getDerAttrs() {
+        return derAttrs;
+    }
+
+    @XmlElementWrapper(name = "virAttrs")
+    @XmlElement(name = "attribute")
+    @JsonProperty("virAttrs")
+    public List<String> getVirAttrs() {
+        return virAttrs;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractSubjectReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractSubjectReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractSubjectReportletConf.java
deleted file mode 100644
index 8b3da49..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractSubjectReportletConf.java
+++ /dev/null
@@ -1,84 +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.report;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.annotation.FormAttributeField;
-import org.apache.syncope.common.lib.types.IntMappingType;
-
-@XmlType
-public abstract class AbstractSubjectReportletConf extends AbstractReportletConf {
-
-    private static final long serialVersionUID = -5388597116592877789L;
-
-    @FormAttributeField(userSearch = true)
-    protected String matchingCond;
-
-    @FormAttributeField(schema = IntMappingType.UserPlainSchema)
-    protected final List<String> plainAttrs = new ArrayList<>();
-
-    @FormAttributeField(schema = IntMappingType.UserDerivedSchema)
-    protected final List<String> derAttrs = new ArrayList<>();
-
-    @FormAttributeField(schema = IntMappingType.UserVirtualSchema)
-    protected final List<String> virAttrs = new ArrayList<>();
-
-    public AbstractSubjectReportletConf() {
-        super();
-    }
-
-    public AbstractSubjectReportletConf(final String name) {
-        super(name);
-    }
-
-    public String getMatchingCond() {
-        return matchingCond;
-    }
-
-    public void setMatchingCond(final String matchingCond) {
-        this.matchingCond = matchingCond;
-    }
-
-    @XmlElementWrapper(name = "plainAttrs")
-    @XmlElement(name = "attribute")
-    @JsonProperty("plainAttrs")
-    public List<String> getPlainAttrs() {
-        return plainAttrs;
-    }
-
-    @XmlElementWrapper(name = "derAttrs")
-    @XmlElement(name = "attribute")
-    @JsonProperty("derAttrs")
-    public List<String> getDerAttrs() {
-        return derAttrs;
-    }
-
-    @XmlElementWrapper(name = "virAttrs")
-    @XmlElement(name = "attribute")
-    @JsonProperty("virAttrs")
-    public List<String> getVirAttrs() {
-        return virAttrs;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
index de7bff3..861795c 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
@@ -29,7 +29,7 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "groupReportletConf")
 @XmlType
-public class GroupReportletConf extends AbstractSubjectReportletConf {
+public class GroupReportletConf extends AbstractAnyReportletConf {
 
     private static final long serialVersionUID = -8488503068032439699L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
index ce783ff..72daf7b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
@@ -29,7 +29,7 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "userReportletConf")
 @XmlType
-public class UserReportletConf extends AbstractSubjectReportletConf {
+public class UserReportletConf extends AbstractAnyReportletConf {
 
     @XmlEnum
     @XmlType(name = "userReportletConfFeature")

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
index 7a27a2b..9a68a8d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SearchableFields.java
@@ -25,10 +25,11 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 public final class SearchableFields {
 
@@ -36,17 +37,19 @@ public final class SearchableFields {
         "serialVersionUID", "password"
     };
 
-    public static List<String> get(final SubjectType subjectType) {
-        return get(subjectType == SubjectType.USER
+    public static List<String> get(final AnyTypeKind anyTypeKind) {
+        return get(anyTypeKind == AnyTypeKind.USER
                 ? UserTO.class
-                : GroupTO.class);
+                : anyTypeKind == AnyTypeKind.GROUP
+                        ? GroupTO.class
+                        : AnyObjectTO.class);
     }
 
-    public static List<String> get(final Class<? extends AbstractAttributableTO> attributableRef) {
+    public static List<String> get(final Class<? extends AnyTO> anyRef) {
         final List<String> fieldNames = new ArrayList<>();
 
         // loop on class and all superclasses searching for field
-        Class<?> clazz = attributableRef;
+        Class<?> clazz = anyRef;
         while (clazz != null && clazz != Object.class) {
             for (Field field : clazz.getDeclaredFields()) {
                 if (!ArrayUtils.contains(ATTRIBUTES_NOTINCLUDED, field.getName())

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAttributableTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAttributableTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAttributableTO.java
deleted file mode 100644
index c724bb0..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAttributableTO.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlType
-public abstract class AbstractAttributableTO extends ConnObjectTO {
-
-    private static final long serialVersionUID = 4083884098736820255L;
-
-    private long key;
-
-    private final Set<AttrTO> derAttrs = new LinkedHashSet<>();
-
-    private final Set<AttrTO> virAttrs = new LinkedHashSet<>();
-
-    public long getKey() {
-        return key;
-    }
-
-    public void setKey(final long key) {
-        this.key = key;
-    }
-
-    @XmlElementWrapper(name = "derAttrs")
-    @XmlElement(name = "attribute")
-    @JsonProperty("derAttrs")
-    public Set<AttrTO> getDerAttrs() {
-        return derAttrs;
-    }
-
-    @JsonIgnore
-    public Map<String, AttrTO> getDerAttrMap() {
-        Map<String, AttrTO> result = new HashMap<>(derAttrs.size());
-        for (AttrTO attributeTO : derAttrs) {
-            result.put(attributeTO.getSchema(), attributeTO);
-        }
-
-        return Collections.unmodifiableMap(result);
-    }
-
-    @XmlElementWrapper(name = "virAttrs")
-    @XmlElement(name = "attribute")
-    @JsonProperty("virAttrs")
-    public Set<AttrTO> getVirAttrs() {
-        return virAttrs;
-    }
-
-    @JsonIgnore
-    public Map<String, AttrTO> getVirAttrMap() {
-        Map<String, AttrTO> result = new HashMap<>(virAttrs.size());
-        for (AttrTO attributeTO : virAttrs) {
-            result.put(attributeTO.getSchema(), attributeTO);
-        }
-
-        return Collections.unmodifiableMap(result);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSubjectTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSubjectTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSubjectTO.java
deleted file mode 100644
index ae21f12..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSubjectTO.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.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlType
-public abstract class AbstractSubjectTO extends AbstractAttributableTO {
-
-    private static final long serialVersionUID = 114668706977919206L;
-
-    private String realm;
-
-    private final Set<String> resources = new HashSet<>();
-
-    private final List<PropagationStatus> propagationStatusTOs = new ArrayList<>();
-
-    public String getRealm() {
-        return realm;
-    }
-
-    public void setRealm(final String realm) {
-        this.realm = realm;
-    }
-
-    @XmlElementWrapper(name = "resources")
-    @XmlElement(name = "resource")
-    @JsonProperty("resources")
-    public Set<String> getResources() {
-        return resources;
-    }
-
-    @XmlElementWrapper(name = "propagationStatuses")
-    @XmlElement(name = "propagationStatus")
-    @JsonProperty("propagationStatuses")
-    public List<PropagationStatus> getPropagationStatusTOs() {
-        return propagationStatusTOs;
-    }
-
-}


[24/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index 009e881..87f2ea5 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -27,52 +27,43 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.jexl2.JexlContext;
 import org.apache.commons.jexl2.MapContext;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.CollectionUtils2;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.FrameworkUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -92,7 +83,7 @@ public final class MappingUtils {
     public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
             final Collection<T> items, final IntMappingType type) {
 
-        return CollectionUtils2.find(items, new Predicate<T>() {
+        return CollectionUtils.select(items, new Predicate<T>() {
 
             @Override
             public boolean evaluate(final T item) {
@@ -104,7 +95,7 @@ public final class MappingUtils {
     public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
             final Collection<T> items, final String intAttrName, final IntMappingType type) {
 
-        return CollectionUtils2.find(items, new Predicate<T>() {
+        return CollectionUtils.select(items, new Predicate<T>() {
 
             @Override
             public boolean evaluate(final T item) {
@@ -116,7 +107,7 @@ public final class MappingUtils {
     public static <T extends MappingItem> Collection<T> getMatchingMappingItems(
             final Collection<T> items, final String intAttrName) {
 
-        return CollectionUtils2.find(items, new Predicate<T>() {
+        return CollectionUtils.select(items, new Predicate<T>() {
 
             @Override
             public boolean evaluate(final T item) {
@@ -128,71 +119,52 @@ public final class MappingUtils {
     /**
      * Prepare attributes for sending to a connector instance.
      *
-     * @param attrUtils user / group
-     * @param subject given user / group
+     * @param anyUtils any object
+     * @param any given any object
      * @param password clear-text password
      * @param changePwd whether password should be included for propagation attributes or not
      * @param vAttrsToBeRemoved virtual attributes to be removed
      * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param membVAttrsToBeRemoved membership virtual attributes to be removed
-     * @param membVAttrsToBeUpdated membership virtual attributes to be added
-     * @param enable whether user must be enabled or not
-     * @param resource target resource
+     * @param enable whether any object must be enabled or not
+     * @param provision provision information
      * @return account link + prepared attributes
      */
     public static Pair<String, Set<Attribute>> prepareAttributes(
-            final AttributableUtils attrUtils, final Subject<?, ?, ?> subject,
+            final AnyUtils anyUtils, final Any<?, ?, ?> any,
             final String password,
             final boolean changePwd,
             final Set<String> vAttrsToBeRemoved,
             final Map<String, AttrMod> vAttrsToBeUpdated,
-            final Set<String> membVAttrsToBeRemoved,
-            final Map<String, AttrMod> membVAttrsToBeUpdated,
             final Boolean enable,
-            final ExternalResource resource) {
+            final Provision provision) {
 
-        LOG.debug("Preparing resource attributes for {} on resource {} with attributes {}",
-                subject, resource, subject.getPlainAttrs());
+        LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
+                any, provision, any.getPlainAttrs());
 
-        final ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        final VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
-        final PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
+        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+        VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
+        PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
 
         Set<Attribute> attributes = new HashSet<>();
-        String accountId = null;
+        String connObjectKey = null;
 
-        for (MappingItem mapping : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+        for (MappingItem mapping : anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
             LOG.debug("Processing schema {}", mapping.getIntAttrName());
 
             try {
-                if ((attrUtils.getType() == AttributableType.USER
-                        && mapping.getIntMappingType() == IntMappingType.UserVirtualSchema)
-                        || (attrUtils.getType() == AttributableType.GROUP
-                        && mapping.getIntMappingType() == IntMappingType.GroupVirtualSchema)) {
-
-                    LOG.debug("Expire entry cache {}-{}", subject.getKey(), mapping.getIntAttrName());
-                    virAttrCache.expire(attrUtils.getType(), subject.getKey(), mapping.getIntAttrName());
-                }
+                if (mapping.getIntMappingType() == IntMappingType.UserVirtualSchema
+                        || mapping.getIntMappingType() == IntMappingType.GroupVirtualSchema
+                        || mapping.getIntMappingType() == IntMappingType.AnyVirtualSchema) {
 
-                // SYNCOPE-458 expire cache also for membership virtual schemas
-                if (attrUtils.getType() == AttributableType.USER && mapping.getIntMappingType()
-                        == IntMappingType.MembershipVirtualSchema && (subject instanceof User)) {
-
-                    final User user = (User) subject;
-                    for (Membership membership : user.getMemberships()) {
-                        LOG.debug("Expire entry cache {}-{} for membership {}", subject.getKey(),
-                                mapping.getIntAttrName(), membership);
-                        virAttrCache.expire(AttributableType.MEMBERSHIP, membership.getKey(),
-                                mapping.getIntAttrName());
-                    }
+                    LOG.debug("Expire entry cache {}-{}", any.getKey(), mapping.getIntAttrName());
+                    virAttrCache.expire(any.getType().getKey(), any.getKey(), mapping.getIntAttrName());
                 }
 
                 Pair<String, Attribute> preparedAttr = prepareAttr(
-                        resource, mapping, subject, password, passwordGenerator, vAttrsToBeRemoved, vAttrsToBeUpdated,
-                        membVAttrsToBeRemoved, membVAttrsToBeUpdated);
+                        provision, mapping, any, password, passwordGenerator, vAttrsToBeRemoved, vAttrsToBeUpdated);
 
                 if (preparedAttr != null && preparedAttr.getKey() != null) {
-                    accountId = preparedAttr.getKey();
+                    connObjectKey = preparedAttr.getKey();
                 }
 
                 if (preparedAttr != null && preparedAttr.getValue() != null) {
@@ -215,12 +187,13 @@ public final class MappingUtils {
         }
 
         final Attribute accountIdExtAttr =
-                AttributeUtil.find(attrUtils.getAccountIdItem(resource).getExtAttrName(), attributes);
+                AttributeUtil.find(anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), attributes);
         if (accountIdExtAttr != null) {
             attributes.remove(accountIdExtAttr);
-            attributes.add(AttributeBuilder.build(attrUtils.getAccountIdItem(resource).getExtAttrName(), accountId));
+            attributes.add(AttributeBuilder.build(
+                    anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
         }
-        attributes.add(evaluateNAME(subject, resource, accountId));
+        attributes.add(evaluateNAME(any, provision, connObjectKey));
 
         if (enable != null) {
             attributes.add(AttributeBuilder.buildEnabled(enable));
@@ -232,15 +205,15 @@ public final class MappingUtils {
             }
         }
 
-        return new ImmutablePair<>(accountId, attributes);
+        return new ImmutablePair<>(connObjectKey, attributes);
     }
 
     /**
      * Prepare an attribute to be sent to a connector instance.
      *
-     * @param resource target resource
+     * @param provision external resource
      * @param mapItem mapping item for the given attribute
-     * @param subject given user
+     * @param any any object
      * @param password clear-text password
      * @param passwordGenerator password generator
      * @param vAttrsToBeRemoved virtual attributes to be removed
@@ -249,40 +222,38 @@ public final class MappingUtils {
      */
     @SuppressWarnings("unchecked")
     private static Pair<String, Attribute> prepareAttr(
-            final ExternalResource resource, final MappingItem mapItem,
-            final Subject<?, ?, ?> subject, final String password, final PasswordGenerator passwordGenerator,
-            final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated,
-            final Set<String> membVAttrsToBeRemoved, final Map<String, AttrMod> membVAttrsToBeUpdated) {
+            final Provision provision, final MappingItem mapItem,
+            final Any<?, ?, ?> any, final String password, final PasswordGenerator passwordGenerator,
+            final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated) {
 
-        List<Attributable<?, ?, ?>> attributables = new ArrayList<>();
+        List<Any<?, ?, ?>> anys = new ArrayList<>();
 
         ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        AttributableUtilsFactory attrUtilsFactory = context.getBean(AttributableUtilsFactory.class);
+        AnyUtilsFactory anyUtilsFactory = context.getBean(AnyUtilsFactory.class);
         ConnObjectUtils connObjectUtils = context.getBean(ConnObjectUtils.class);
 
-        switch (mapItem.getIntMappingType().getAttributableType()) {
+        switch (mapItem.getIntMappingType().getAnyTypeKind()) {
             case USER:
-                if (subject instanceof User) {
-                    attributables.add(subject);
+                if (any instanceof User) {
+                    anys.add(any);
                 }
                 break;
 
             case GROUP:
-                if (subject instanceof User) {
+                if (any instanceof User) {
                     UserDAO userDAO = context.getBean(UserDAO.class);
-                    for (Group group : userDAO.findAllGroups((User) subject)) {
-                        connObjectUtils.retrieveVirAttrValues(group, attrUtilsFactory.getInstance(group));
-                        attributables.add(group);
+                    for (Group group : userDAO.findAllGroups((User) any)) {
+                        connObjectUtils.retrieveVirAttrValues(group);
+                        anys.add(group);
                     }
-                }
-                if (subject instanceof Group) {
-                    attributables.add(subject);
+                } else if (any instanceof Group) {
+                    anys.add(any);
                 }
                 break;
 
-            case MEMBERSHIP:
-                if (subject instanceof User) {
-                    attributables.addAll(((User) subject).getMemberships());
+            case ANY_OBJECT:
+                if (any instanceof AnyObject) {
+                    anys.add(any);
                 }
                 break;
 
@@ -290,8 +261,7 @@ public final class MappingUtils {
         }
 
         List<PlainAttrValue> values = getIntValues(
-                resource, mapItem, attributables, vAttrsToBeRemoved, vAttrsToBeUpdated, membVAttrsToBeRemoved,
-                membVAttrsToBeUpdated);
+                provision, mapItem, anys, vAttrsToBeRemoved, vAttrsToBeUpdated);
 
         PlainSchema schema = null;
         boolean readOnlyVirSchema = false;
@@ -301,19 +271,17 @@ public final class MappingUtils {
         switch (mapItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case MembershipPlainSchema:
+            case AnyPlainSchema:
                 final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
-                schema = plainSchemaDAO.find(
-                        mapItem.getIntAttrName(), getIntMappingTypeClass(mapItem.getIntMappingType()));
+                schema = plainSchemaDAO.find(mapItem.getIntAttrName());
                 schemaType = schema == null ? AttrSchemaType.String : schema.getType();
                 break;
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-            case MembershipVirtualSchema:
+            case AnyVirtualSchema:
                 VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
-                VirSchema virSchema = virSchemaDAO.find(
-                        mapItem.getIntAttrName(), getIntMappingTypeClass(mapItem.getIntMappingType()));
+                VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
                 readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
                 schemaType = AttrSchemaType.String;
                 break;
@@ -326,7 +294,7 @@ public final class MappingUtils {
 
         LOG.debug("Define mapping for: "
                 + "\n* ExtAttrName " + extAttrName
-                + "\n* is accountId " + mapItem.isAccountid()
+                + "\n* is accountId " + mapItem.isConnObjectKey()
                 + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
                 + "\n* mandatory condition " + mapItem.getMandatoryCondition()
                 + "\n* Schema " + mapItem.getIntAttrName()
@@ -337,7 +305,7 @@ public final class MappingUtils {
         if (readOnlyVirSchema) {
             result = null;
         } else {
-            final List<Object> objValues = new ArrayList<>();
+            List<Object> objValues = new ArrayList<>();
 
             for (PlainAttrValue value : values) {
                 if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) {
@@ -347,19 +315,19 @@ public final class MappingUtils {
                 }
             }
 
-            if (mapItem.isAccountid()) {
+            if (mapItem.isConnObjectKey()) {
                 result = new ImmutablePair<>(objValues.iterator().next().toString(), null);
-            } else if (mapItem.isPassword() && subject instanceof User) {
+            } else if (mapItem.isPassword() && any instanceof User) {
                 String passwordAttrValue = password;
                 if (StringUtils.isBlank(passwordAttrValue)) {
-                    User user = (User) subject;
+                    User user = (User) any;
                     if (user.canDecodePassword()) {
                         try {
                             passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
                         } catch (Exception e) {
                             LOG.error("Could not decode password for {}", user, e);
                         }
-                    } else if (resource.isRandomPwdIfNotProvided()) {
+                    } else if (provision.getResource().isRandomPwdIfNotProvided()) {
                         try {
                             passwordAttrValue = passwordGenerator.generate(user);
                         } catch (InvalidPasswordPolicySpecException e) {
@@ -376,8 +344,9 @@ public final class MappingUtils {
                             AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
                 }
             } else {
-                if ((schema != null && schema.isMultivalue()) || attrUtilsFactory.getInstance(subject).getType()
-                        != mapItem.getIntMappingType().getAttributableType()) {
+                if ((schema != null && schema.isMultivalue())
+                        || anyUtilsFactory.getInstance(any).getAnyTypeKind()
+                        != mapItem.getIntMappingType().getAnyTypeKind()) {
 
                     result = new ImmutablePair<>(
                             null,
@@ -398,31 +367,31 @@ public final class MappingUtils {
      * Build __NAME__ for propagation. First look if there ia a defined accountLink for the given resource (and in this
      * case evaluate as JEXL); otherwise, take given accountId.
      *
-     * @param subject given user / group
-     * @param resource target resource
-     * @param accountId accountId
+     * @param any given any object
+     * @param provision external resource
+     * @param connObjectKey connector object key
      * @return the value to be propagated as __NAME__
      */
-    public static Name evaluateNAME(final Subject<?, ?, ?> subject,
-            final ExternalResource resource, final String accountId) {
+    public static Name evaluateNAME(final Any<?, ?, ?> any,
+            final Provision provision, final String connObjectKey) {
 
-        final AttributableUtilsFactory attrUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AttributableUtilsFactory.class);
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(subject);
+        final AnyUtilsFactory anyUtilsFactory =
+                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
+        final AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
-        if (StringUtils.isBlank(accountId)) {
+        if (StringUtils.isBlank(connObjectKey)) {
             // LOG error but avoid to throw exception: leave it to the external resource
-            LOG.error("Missing accountId for '{}': ", resource.getKey());
+            LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
         }
 
         // Evaluate AccountLink expression
         String evalAccountLink = null;
-        if (StringUtils.isNotBlank(attrUtils.getAccountLink(resource))) {
+        if (StringUtils.isNotBlank(anyUtils.getConnObjectLink(provision))) {
             final JexlContext jexlContext = new MapContext();
-            JexlUtils.addFieldsToContext(subject, jexlContext);
-            JexlUtils.addAttrsToContext(subject.getPlainAttrs(), jexlContext);
-            JexlUtils.addDerAttrsToContext(subject.getDerAttrs(), subject.getPlainAttrs(), jexlContext);
-            evalAccountLink = JexlUtils.evaluate(attrUtils.getAccountLink(resource), jexlContext);
+            JexlUtils.addFieldsToContext(any, jexlContext);
+            JexlUtils.addAttrsToContext(any.getPlainAttrs(), jexlContext);
+            JexlUtils.addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
+            evalAccountLink = JexlUtils.evaluate(anyUtils.getConnObjectLink(provision), jexlContext);
         }
 
         // If AccountLink evaluates to an empty string, just use the provided AccountId as Name(),
@@ -430,8 +399,8 @@ public final class MappingUtils {
         Name name;
         if (StringUtils.isBlank(evalAccountLink)) {
             // add AccountId as __NAME__ attribute ...
-            LOG.debug("Add AccountId [{}] as __NAME__", accountId);
-            name = new Name(accountId);
+            LOG.debug("Add AccountId [{}] as __NAME__", connObjectKey);
+            name = new Name(connObjectKey);
         } else {
             LOG.debug("Add AccountLink [{}] as __NAME__", evalAccountLink);
             name = new Name(evalAccountLink);
@@ -443,51 +412,45 @@ public final class MappingUtils {
         return name;
     }
 
-    private static String getGroupOwnerValue(
-            final ExternalResource resource, final Subject<?, ?, ?> subject) {
-
-        AttributableUtilsFactory attrUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AttributableUtilsFactory.class);
+    private static String getGroupOwnerValue(final Provision provision, final Any<?, ?, ?> any) {
+        AnyUtilsFactory anyUtilsFactory =
+                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
 
         Pair<String, Attribute> preparedAttr = prepareAttr(
-                resource, attrUtilsFactory.getInstance(subject).getAccountIdItem(resource), subject, null, null,
-                Collections.<String>emptySet(), Collections.<String, AttrMod>emptyMap(),
-                Collections.<String>emptySet(), Collections.<String, AttrMod>emptyMap());
-        String accountId = preparedAttr.getKey();
+                provision, anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision),
+                any, null, null, Collections.<String>emptySet(), Collections.<String, AttrMod>emptyMap());
+        String connObjectKey = preparedAttr.getKey();
 
-        final Name groupOwnerName = evaluateNAME(subject, resource, accountId);
+        final Name groupOwnerName = evaluateNAME(any, provision, connObjectKey);
         return groupOwnerName.getNameValue();
     }
 
     /**
      * Get attribute values.
      *
-     * @param resource target resource
+     * @param provision provision information
      * @param mappingItem mapping item
-     * @param attributables list of attributables
+     * @param anys any objects
      * @param vAttrsToBeRemoved virtual attributes to be removed
      * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param membVAttrsToBeRemoved membership virtual attributes to be removed
-     * @param membVAttrsToBeUpdated membership virtual attributes to be added
      * @return attribute values.
      */
-    public static List<PlainAttrValue> getIntValues(final ExternalResource resource,
-            final MappingItem mappingItem, final List<Attributable<?, ?, ?>> attributables,
-            final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated,
-            final Set<String> membVAttrsToBeRemoved, final Map<String, AttrMod> membVAttrsToBeUpdated) {
+    public static List<PlainAttrValue> getIntValues(final Provision provision,
+            final MappingItem mappingItem, final List<Any<?, ?, ?>> anys,
+            final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated) {
 
-        LOG.debug("Get attributes for '{}' and mapping type '{}'", attributables, mappingItem.getIntMappingType());
+        LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
 
-        final EntityFactory entityFactory =
+        EntityFactory entityFactory =
                 ApplicationContextProvider.getApplicationContext().getBean(EntityFactory.class);
         List<PlainAttrValue> values = new ArrayList<>();
         PlainAttrValue attrValue;
         switch (mappingItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case MembershipPlainSchema:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    final PlainAttr attr = attributable.getPlainAttr(mappingItem.getIntAttrName());
+            case AnyPlainSchema:
+                for (Any<?, ?, ?> any : anys) {
+                    PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
                         if (attr.getUniqueValue() != null) {
                             values.add(attr.getUniqueValue());
@@ -507,8 +470,9 @@ public final class MappingUtils {
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    VirAttr virAttr = attributable.getVirAttr(mappingItem.getIntAttrName());
+            case AnyVirtualSchema:
+                for (Any<?, ?, ?> any : anys) {
+                    VirAttr<?> virAttr = any.getVirAttr(mappingItem.getIntAttrName());
                     if (virAttr != null) {
                         if (vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
                             if (vAttrsToBeUpdated.containsKey(mappingItem.getIntAttrName())) {
@@ -535,55 +499,21 @@ public final class MappingUtils {
                             + "\n* IntAttrName {}"
                             + "\n* IntMappingType {}"
                             + "\n* Attribute values {}",
-                            attributable.getClass().getSimpleName(),
-                            virAttr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
-                }
-                break;
-
-            case MembershipVirtualSchema:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    VirAttr virAttr = attributable.getVirAttr(mappingItem.getIntAttrName());
-                    if (virAttr != null) {
-                        if (membVAttrsToBeRemoved != null && membVAttrsToBeUpdated != null) {
-                            if (membVAttrsToBeUpdated.containsKey(mappingItem.getIntAttrName())) {
-                                virAttr.getValues().clear();
-                                virAttr.getValues().addAll(
-                                        membVAttrsToBeUpdated.get(mappingItem.getIntAttrName()).getValuesToBeAdded());
-                            } else if (membVAttrsToBeRemoved.contains(mappingItem.getIntAttrName())) {
-                                virAttr.getValues().clear();
-                            } else {
-                                throw new IllegalArgumentException("Don't need to update membership virtual attribute '"
-                                        + mappingItem.getIntAttrName() + "'");
-                            }
-                        }
-                        if (virAttr.getValues() != null) {
-                            for (String value : virAttr.getValues()) {
-                                attrValue = entityFactory.newEntity(UPlainAttrValue.class);
-                                attrValue.setStringValue(value);
-                                values.add(attrValue);
-                            }
-                        }
-                    }
-
-                    LOG.debug("Retrieved {} virtual attribute {}"
-                            + "\n* IntAttrName {}"
-                            + "\n* IntMappingType {}"
-                            + "\n* Attribute values {}",
-                            attributable.getClass().getSimpleName(),
+                            any.getClass().getSimpleName(),
                             virAttr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
                 }
                 break;
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case MembershipDerivedSchema:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    DerAttr derAttr = attributable.getDerAttr(mappingItem.getIntAttrName());
+            case AnyDerivedSchema:
+                for (Any<?, ?, ?> any : anys) {
+                    DerAttr<?> derAttr = any.getDerAttr(mappingItem.getIntAttrName());
                     if (derAttr != null) {
-                        attrValue = attributable instanceof Group
+                        attrValue = any instanceof Group
                                 ? entityFactory.newEntity(GPlainAttrValue.class)
                                 : entityFactory.newEntity(UPlainAttrValue.class);
-                        attrValue.setStringValue(derAttr.getValue(attributable.getPlainAttrs()));
+                        attrValue.setStringValue(derAttr.getValue(any.getPlainAttrs()));
                         values.add(attrValue);
                     }
 
@@ -597,44 +527,52 @@ public final class MappingUtils {
 
             case UserId:
             case GroupId:
-            case MembershipId:
-                for (Attributable<?, ?, ?> attributable : attributables) {
+            case AnyId:
+                for (Any<?, ?, ?> any : anys) {
                     attrValue = entityFactory.newEntity(UPlainAttrValue.class);
-                    attrValue.setStringValue(attributable.getKey().toString());
+                    attrValue.setStringValue(any.getKey().toString());
                     values.add(attrValue);
                 }
                 break;
 
             case Username:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    if (attributable instanceof User) {
+                for (Any<?, ?, ?> any : anys) {
+                    if (any instanceof User) {
                         attrValue = entityFactory.newEntity(UPlainAttrValue.class);
-                        attrValue.setStringValue(((User) attributable).getUsername());
+                        attrValue.setStringValue(((User) any).getUsername());
                         values.add(attrValue);
                     }
                 }
                 break;
 
             case GroupName:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    if (attributable instanceof Group) {
+                for (Any<?, ?, ?> any : anys) {
+                    if (any instanceof Group) {
                         attrValue = entityFactory.newEntity(GPlainAttrValue.class);
-                        attrValue.setStringValue(((Group) attributable).getName());
+                        attrValue.setStringValue(((Group) any).getName());
                         values.add(attrValue);
                     }
                 }
                 break;
 
             case GroupOwnerSchema:
-                for (Attributable<?, ?, ?> attributable : attributables) {
-                    if (attributable instanceof Group) {
-                        Group group = (Group) attributable;
+                AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class);
+                Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
+                        ? null
+                        : provision.getMapping();
+                Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
+                        ? null
+                        : provision.getMapping();
+
+                for (Any<?, ?, ?> any : anys) {
+                    if (any instanceof Group) {
+                        Group group = (Group) any;
                         String groupOwnerValue = null;
-                        if (group.getUserOwner() != null && resource.getUmapping() != null) {
-                            groupOwnerValue = getGroupOwnerValue(resource, group.getUserOwner());
+                        if (group.getUserOwner() != null && uMapping != null) {
+                            groupOwnerValue = getGroupOwnerValue(provision, group.getUserOwner());
                         }
-                        if (group.getGroupOwner() != null && resource.getGmapping() != null) {
-                            groupOwnerValue = getGroupOwnerValue(resource, group.getGroupOwner());
+                        if (group.getGroupOwner() != null && gMapping != null) {
+                            groupOwnerValue = getGroupOwnerValue(provision, group.getGroupOwner());
                         }
 
                         if (StringUtils.isNotBlank(groupOwnerValue)) {
@@ -655,78 +593,22 @@ public final class MappingUtils {
     }
 
     /**
-     * Get accountId internal value.
+     * Get connObjectKey internal value.
      *
-     * @param subject subject
-     * @param accountIdItem accountId mapping item
-     * @param resource external resource
-     * @return accountId internal value
+     * @param any any object
+     * @param provision provision information
+     * @return connObjectKey internal value
      */
-    public static String getAccountIdValue(final Subject<?, ?, ?> subject,
-            final ExternalResource resource, final MappingItem accountIdItem) {
+    public static String getConnObjectKeyValue(final Any<?, ?, ?> any, final Provision provision) {
 
-        List<PlainAttrValue> values = getIntValues(resource, accountIdItem,
-                Collections.<Attributable<?, ?, ?>>singletonList(subject), null, null, null, null);
+        List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
+                Collections.<Any<?, ?, ?>>singletonList(any), null, null);
         return values == null || values.isEmpty()
                 ? null
                 : values.get(0).getValueAsString();
     }
 
     /**
-     * For given source mapping type, return the corresponding Class object.
-     *
-     * @param intMappingType source mapping type
-     * @return corresponding Class object, if any (can be null)
-     */
-    @SuppressWarnings("rawtypes")
-    public static Class getIntMappingTypeClass(final IntMappingType intMappingType) {
-        Class result;
-
-        switch (intMappingType) {
-            case UserPlainSchema:
-                result = UPlainSchema.class;
-                break;
-
-            case GroupPlainSchema:
-                result = GPlainSchema.class;
-                break;
-
-            case MembershipPlainSchema:
-                result = MPlainSchema.class;
-                break;
-
-            case UserDerivedSchema:
-                result = UDerSchema.class;
-                break;
-
-            case GroupDerivedSchema:
-                result = GDerSchema.class;
-                break;
-
-            case MembershipDerivedSchema:
-                result = MDerSchema.class;
-                break;
-
-            case UserVirtualSchema:
-                result = UVirSchema.class;
-                break;
-
-            case GroupVirtualSchema:
-                result = GVirSchema.class;
-                break;
-
-            case MembershipVirtualSchema:
-                result = MVirSchema.class;
-                break;
-
-            default:
-                result = null;
-        }
-
-        return result;
-    }
-
-    /**
      * Private default constructor, for static-only classes.
      */
     private MappingUtils() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
index bc3159c..83e98ec 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
@@ -33,13 +33,13 @@ import org.apache.commons.jexl2.JexlException;
 import org.apache.commons.jexl2.MapContext;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -146,14 +146,14 @@ public final class JexlUtils {
         return context;
     }
 
-    public static JexlContext addAttrsToContext(final Collection<? extends PlainAttr> attrs,
+    public static JexlContext addAttrsToContext(final Collection<? extends PlainAttr<?>> attrs,
             final JexlContext jexlContext) {
 
         JexlContext context = jexlContext == null
                 ? new MapContext()
                 : jexlContext;
 
-        for (PlainAttr attr : attrs) {
+        for (PlainAttr<?> attr : attrs) {
             if (attr.getSchema() != null) {
                 List<String> attrValues = attr.getValuesAsStrings();
                 String expressionValue = attrValues.isEmpty()
@@ -170,13 +170,13 @@ public final class JexlUtils {
     }
 
     public static JexlContext addDerAttrsToContext(final Collection<? extends DerAttr> derAttrs,
-            final Collection<? extends PlainAttr> attrs, final JexlContext jexlContext) {
+            final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
 
         JexlContext context = jexlContext == null
                 ? new MapContext()
                 : jexlContext;
 
-        for (DerAttr derAttr : derAttrs) {
+        for (DerAttr<?> derAttr : derAttrs) {
             if (derAttr.getSchema() != null) {
                 String expressionValue = derAttr.getValue(attrs);
                 if (expressionValue == null) {
@@ -199,7 +199,7 @@ public final class JexlUtils {
                 ? new MapContext()
                 : jexlContext;
 
-        for (VirAttr virAttr : virAttrs) {
+        for (VirAttr<?> virAttr : virAttrs) {
             if (virAttr.getSchema() != null) {
                 List<String> attrValues = virAttr.getValues();
                 String expressionValue = attrValues.isEmpty()
@@ -216,33 +216,33 @@ public final class JexlUtils {
     }
 
     public static boolean evaluateMandatoryCondition(
-            final String mandatoryCondition, final Attributable<?, ?, ?> attributable) {
+            final String mandatoryCondition, final Any<?, ?, ?> any) {
 
         JexlContext jexlContext = new MapContext();
-        addAttrsToContext(attributable.getPlainAttrs(), jexlContext);
-        addDerAttrsToContext(attributable.getDerAttrs(), attributable.getPlainAttrs(), jexlContext);
-        addVirAttrsToContext(attributable.getVirAttrs(), jexlContext);
+        addAttrsToContext(any.getPlainAttrs(), jexlContext);
+        addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
+        addVirAttrsToContext(any.getVirAttrs(), jexlContext);
 
         return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
     }
 
     public static String evaluate(final String expression,
-            final Attributable<?, ?, ?> attributable, final Collection<? extends PlainAttr> attributes) {
+            final Any<?, ?, ?> any, final Collection<? extends PlainAttr<?>> attributes) {
 
         final JexlContext jexlContext = new MapContext();
         JexlUtils.addAttrsToContext(attributes, jexlContext);
-        JexlUtils.addFieldsToContext(attributable, jexlContext);
+        JexlUtils.addFieldsToContext(any, jexlContext);
 
         // Evaluate expression using the context prepared before
         return evaluate(expression, jexlContext);
     }
 
-    public static String evaluate(final String expression, final AbstractAttributableTO attributableTO) {
+    public static String evaluate(final String expression, final AnyTO anyTO) {
         final JexlContext context = new MapContext();
 
-        addFieldsToContext(attributableTO, context);
+        addFieldsToContext(anyTO, context);
 
-        for (AttrTO plainAttr : attributableTO.getPlainAttrs()) {
+        for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
             List<String> values = plainAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY
@@ -252,7 +252,7 @@ public final class JexlUtils {
 
             context.set(plainAttr.getSchema(), expressionValue);
         }
-        for (AttrTO derAttr : attributableTO.getDerAttrs()) {
+        for (AttrTO derAttr : anyTO.getDerAttrs()) {
             List<String> values = derAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY
@@ -262,7 +262,7 @@ public final class JexlUtils {
 
             context.set(derAttr.getSchema(), expressionValue);
         }
-        for (AttrTO virAttr : attributableTO.getVirAttrs()) {
+        for (AttrTO virAttr : anyTO.getVirAttrs()) {
             List<String> values = virAttr.getValues();
             String expressionValue = values.isEmpty()
                     ? StringUtils.EMPTY

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
index b9cfb64..52fa0d8 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
@@ -22,7 +22,7 @@ import java.util.List;
 import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.common.lib.types.PolicySpec;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -40,7 +40,7 @@ public class PolicyEvaluator {
     private static final Logger LOG = LoggerFactory.getLogger(PolicyEvaluator.class);
 
     @SuppressWarnings("unchecked")
-    public <T extends PolicySpec> T evaluate(final Policy policy, final Attributable<?, ?, ?> attributable) {
+    public <T extends PolicySpec> T evaluate(final Policy policy, final Any<?, ?, ?> any) {
         if (policy == null) {
             return null;
         }
@@ -54,7 +54,7 @@ public class PolicyEvaluator {
                 BeanUtils.copyProperties(ppSpec, evaluatedPPSpec, new String[] { "schemasNotPermitted" });
 
                 for (String schema : ppSpec.getSchemasNotPermitted()) {
-                    PlainAttr attr = attributable.getPlainAttr(schema);
+                    PlainAttr attr = any.getPlainAttr(schema);
                     if (attr != null) {
                         List<String> values = attr.getValuesAsStrings();
                         if (values != null && !values.isEmpty()) {
@@ -64,13 +64,13 @@ public class PolicyEvaluator {
                 }
 
                 // Password history verification and update
-                if (!(attributable instanceof User)) {
-                    LOG.error("Cannot check previous passwords. attributable is not a user object: {}",
-                            attributable.getClass().getName());
+                if (!(any instanceof User)) {
+                    LOG.error("Cannot check previous passwords. instance is not user object: {}",
+                            any.getClass().getName());
                     result = (T) evaluatedPPSpec;
                     break;
                 }
-                User user = (User) attributable;
+                User user = (User) any;
                 if (user.verifyPasswordHistory(user.getClearPassword(), ppSpec.getHistoryLength())) {
                     evaluatedPPSpec.getWordsNotPermitted().add(user.getClearPassword());
                 }
@@ -84,7 +84,7 @@ public class PolicyEvaluator {
                 BeanUtils.copyProperties(spec, accountPolicy, new String[] { "schemasNotPermitted" });
 
                 for (String schema : spec.getSchemasNotPermitted()) {
-                    PlainAttr attr = attributable.getPlainAttr(schema);
+                    PlainAttr attr = any.getPlainAttr(schema);
                     if (attr != null) {
                         List<String> values = attr.getValuesAsStrings();
                         if (values != null && !values.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
index cebfb38..a67cbf5 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
@@ -28,26 +28,28 @@ import org.apache.cxf.jaxrs.ext.search.SearchUtils;
 import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
 import org.apache.syncope.common.lib.search.SearchableFields;
 import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.GroupCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
 import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 
 /**
  * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
  */
 public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean, SearchCond> {
 
-    private static final List<String> ATTRIBUTABLE_FIELDS;
+    private static final List<String> ANY_FIELDS;
 
     static {
-        ATTRIBUTABLE_FIELDS = new ArrayList<String>();
-        ATTRIBUTABLE_FIELDS.addAll(SearchableFields.get(UserTO.class));
-        ATTRIBUTABLE_FIELDS.addAll(SearchableFields.get(GroupTO.class));
+        ANY_FIELDS = new ArrayList<>();
+        ANY_FIELDS.addAll(SearchableFields.get(UserTO.class));
+        ANY_FIELDS.addAll(SearchableFields.get(GroupTO.class));
+        ANY_FIELDS.addAll(SearchableFields.get(AnyObjectTO.class));
     }
 
     private SearchCond searchCond;
@@ -61,8 +63,8 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
     }
 
     private AttributeCond createAttributeCond(final String schema) {
-        AttributeCond attributeCond = ATTRIBUTABLE_FIELDS.contains(schema)
-                ? new SubjectCond()
+        AttributeCond attributeCond = ANY_FIELDS.contains(schema)
+                ? new AnyCond()
                 : new AttributeCond();
         attributeCond.setSchema(schema);
         return attributeCond;
@@ -97,7 +99,7 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                 } else {
                     switch (specialAttrName) {
                         case GROUPS:
-                            GroupCond groupCond = new GroupCond();
+                            MembershipCond groupCond = new MembershipCond();
                             groupCond.setGroupKey(Long.valueOf(value));
                             leaf = SearchCond.getLeafCond(groupCond);
                             break;
@@ -124,10 +126,10 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                             && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
 
                         leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
-                    } else if (leaf.getSubjectCond() != null
-                            && leaf.getSubjectCond().getType() == SubjectCond.Type.ISNULL) {
+                    } else if (leaf.getAnyCond() != null
+                            && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
 
-                        leaf.getSubjectCond().setType(AttributeCond.Type.ISNOTNULL);
+                        leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
                     } else {
                         leaf = SearchCond.getNotLeafCond(leaf);
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
index d0501e4..48cafa3 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
@@ -23,7 +23,7 @@ import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+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.misc.policy.InvalidPasswordPolicySpecException;
 import org.apache.syncope.core.misc.policy.PolicyPattern;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index 3ecdd1f..80d2b48 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -23,21 +23,22 @@ import java.util.Iterator;
 import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.SetUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+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.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.identityconnectors.framework.common.objects.Uid;
@@ -77,10 +78,13 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     protected PolicyDAO policyDAO;
 
     @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     protected ConnectorFactory connFactory;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory attrUtilsFactory;
 
     @Resource(name = "adminUser")
     protected String adminUser;
@@ -253,15 +257,15 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
         boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
         LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
 
-        AttributableUtils attrUtils = attrUtilsFactory.getInstance(AttributableType.USER);
+        AnyUtils attrUtils = attrUtilsFactory.getInstance(AnyTypeKind.USER);
         for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
                 itor.hasNext() && !authenticated;) {
 
             ExternalResource resource = itor.next();
-            String accountId = null;
+            String connObjectKey = null;
             try {
-                accountId = MappingUtils.getAccountIdValue(user, resource, attrUtils.getAccountIdItem(resource));
-                Uid uid = connFactory.getConnector(resource).authenticate(accountId, password, null);
+                connObjectKey = MappingUtils.getConnObjectKeyValue(user, resource.getProvision(anyTypeDAO.findUser()));
+                Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
                 if (uid != null) {
                     authenticated = true;
                 }
@@ -269,7 +273,7 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
                 LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
             }
             LOG.debug("{} authenticated on {} as {}: {}",
-                    user.getUsername(), resource.getKey(), accountId, authenticated);
+                    user.getUsername(), resource.getKey(), connObjectKey, authenticated);
         }
 
         return authenticated;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
index 0d6ff52..a179e75 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
@@ -26,9 +26,9 @@ import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.Closure;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.PredicateUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.CollectionUtils2;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.misc.RealmUtils;
@@ -65,7 +65,8 @@ public class SyncopeUserDetailsService implements UserDetailsService {
         if (anonymousUser.equals(username)) {
             authorities.add(new SyncopeGrantedAuthority(Entitlement.ANONYMOUS));
         } else if (adminUser.equals(username)) {
-            CollectionUtils2.collect(Entitlement.values(),
+            CollectionUtils.collect(IteratorUtils.filteredIterator(Entitlement.values().iterator(),
+                    PredicateUtils.notPredicate(PredicateUtils.equalPredicate(Entitlement.ANONYMOUS))),
                     new Transformer<String, SyncopeGrantedAuthority>() {
 
                         @Override
@@ -73,7 +74,6 @@ public class SyncopeUserDetailsService implements UserDetailsService {
                             return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
                         }
                     },
-                    PredicateUtils.notPredicate(PredicateUtils.equalPredicate(Entitlement.ANONYMOUS)),
                     authorities);
         } else {
             org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.find(username);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
index 85df5b7..e5c2815 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
@@ -18,13 +18,13 @@
  */
 package org.apache.syncope.core.misc.security;
 
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 public class UnauthorizedException extends RuntimeException {
 
     private static final long serialVersionUID = 7540587364235915081L;
 
-    public UnauthorizedException(final SubjectType subject, final Long key) {
-        super("Missing entitlement or realm administration for " + subject + " " + key);
+    public UnauthorizedException(final AnyTypeKind type, final Long key) {
+        super("Missing entitlement or realm administration for " + type + " " + key);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
index b3bc11e..26068e9 100644
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
@@ -23,11 +23,11 @@ import static org.junit.Assert.assertEquals;
 import org.apache.syncope.common.lib.search.SpecialAttr;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.GroupCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
 import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
 import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.junit.Test;
 
 public class SearchCondConverterTest {
@@ -37,7 +37,7 @@ public class SearchCondConverterTest {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
         assertEquals("username==rossini", fiqlExpression);
 
-        SubjectCond attrCond = new SubjectCond(AttributeCond.Type.EQ);
+        AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
         attrCond.setSchema("username");
         attrCond.setExpression("rossini");
         SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
@@ -50,7 +50,7 @@ public class SearchCondConverterTest {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
         assertEquals("username==ros*", fiqlExpression);
 
-        AttributeCond attrCond = new SubjectCond(AttributeCond.Type.LIKE);
+        AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
         attrCond.setSchema("username");
         attrCond.setExpression("ros%");
         SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
@@ -87,7 +87,7 @@ public class SearchCondConverterTest {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
         assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
 
-        GroupCond groupCond = new GroupCond();
+        MembershipCond groupCond = new MembershipCond();
         groupCond.setGroupKey(1L);
         SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
new file mode 100644
index 0000000..86c97e3
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+
+public interface AnyDAO<A extends Any<?, ?, ?>> extends DAO<A, Long> {
+
+    A authFind(Long key);
+
+    A find(Long key);
+
+    A findByWorkflowId(String workflowId);
+
+    List<A> findByAttrValue(String schemaName, PlainAttrValue attrValue);
+
+    A findByAttrUniqueValue(String schemaName, PlainAttrValue attrUniqueValue);
+
+    /**
+     * Find any objects by derived attribute value. This method could fail if one or more string literals contained
+     * into the derived attribute value provided derive from identifier (schema name) replacement. When you are going to
+     * specify a derived attribute expression you must be quite sure that string literals used to build the expression
+     * cannot be found into the attribute values used to replace attribute schema names used as identifiers.
+     *
+     * @param schemaName derived schema name
+     * @param value derived attribute value
+     * @return list of any objects
+     */
+    List<A> findByDerAttrValue(String schemaName, String value);
+
+    List<A> findByResource(ExternalResource resource);
+
+    List<A> findAll(Set<String> adminRealms, int page, int itemsPerPage);
+
+    List<A> findAll(Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
+
+    int count(Set<String> adminRealms);
+
+    A save(A any);
+
+    void delete(Long key);
+
+    void delete(A any);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..d01511f
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.Collection;
+import java.util.List;
+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> {
+
+    List<AnyObject> findByAnyType(String anyTypeName);
+
+    List<Group> findDynGroupMemberships(AnyObject anyObject);
+
+    Collection<Group> findAllGroups(AnyObject anyObject);
+
+    Collection<Long> findAllGroupKeys(AnyObject anyObject);
+
+    Collection<ExternalResource> findAllResources(AnyObject anyObject);
+
+    Collection<String> findAllResourceNames(AnyObject anyObject);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
new file mode 100644
index 0000000..f53dff6
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.Any;
+
+public interface AnySearchDAO extends DAO<Any<?, ?, ?>, Long> {
+
+    /**
+     * @param adminRealms realms for which the caller owns the proper entitlement(s)
+     * @param searchCondition the search condition
+     * @param kind any object
+     * @return size of search result
+     */
+    int count(Set<String> adminRealms, SearchCond searchCondition, AnyTypeKind kind);
+
+    /**
+     * @param adminRealms realms for which the caller owns the proper entitlement(s)
+     * @param searchCondition the search condition
+     * @param kind any object
+     * @param <T> any
+     * @return the list of any objects matching the given search condition
+     */
+    <T extends Any<?, ?, ?>> List<T> search(
+            Set<String> adminRealms, SearchCond searchCondition, AnyTypeKind kind);
+
+    /**
+     * @param adminRealms the set of admin groups owned by the caller
+     * @param searchCondition the search condition
+     * @param orderBy list of ordering clauses
+     * @param kind any object
+     * @param <T> any
+     * @return the list of any objects matching the given search condition
+     */
+    <T extends Any<?, ?, ?>> List<T> search(
+            Set<String> adminRealms, SearchCond searchCondition, List<OrderByClause> orderBy, AnyTypeKind kind);
+
+    /**
+     * @param adminRealms realms for which the caller owns the proper entitlement(s)
+     * @param searchCondition the search condition
+     * @param page position of the first result, start from 1
+     * @param itemsPerPage number of results per page
+     * @param orderBy list of ordering clauses
+     * @param kind any object
+     * @param <T> any
+     * @return the list of any objects matching the given search condition (in the given page)
+     */
+    <T extends Any<?, ?, ?>> List<T> search(
+            Set<String> adminRealms, SearchCond searchCondition, int page, int itemsPerPage,
+            List<OrderByClause> orderBy, AnyTypeKind kind);
+
+    /**
+     * Verify if any matches the given search condition.
+     *
+     * @param any to be checked
+     * @param searchCondition to be verified
+     * @param kind any object
+     * @param <T> any
+     * @return true if any matches searchCondition
+     */
+    <T extends Any<?, ?, ?>> boolean matches(T any, SearchCond searchCondition, AnyTypeKind kind);
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
new file mode 100644
index 0000000..bef6812
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+
+public interface AnyTypeDAO extends DAO<AnyType, String> {
+
+    AnyType find(String key);
+
+    AnyType findUser();
+
+    AnyType findGroup();
+
+    List<AnyType> findAll();
+
+    AnyType save(AnyType anyType);
+
+    void delete(String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AttrTemplateDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AttrTemplateDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AttrTemplateDAO.java
deleted file mode 100644
index e4a1f15..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AttrTemplateDAO.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.dao;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-
-public interface AttrTemplateDAO<K extends Schema> extends DAO<AttrTemplate<K>, Long> {
-
-    <T extends AttrTemplate<K>> T find(Long key, Class<T> reference);
-
-    <T extends AttrTemplate<K>> List<Number> findBySchemaName(String schemaName, Class<T> reference);
-
-    <T extends AttrTemplate<K>> void delete(Long key, Class<T> reference);
-
-    <T extends AttrTemplate<K>> void delete(T attrTemplate);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerAttrDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerAttrDAO.java
index 9aa3ac3..d087f20 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerAttrDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerAttrDAO.java
@@ -21,15 +21,15 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 
-public interface DerAttrDAO extends DAO<DerAttr, Long> {
+public interface DerAttrDAO extends DAO<DerAttr<?>, Long> {
 
-    <T extends DerAttr> T find(Long key, Class<T> reference);
+    <T extends DerAttr<?>> T find(Long key, Class<T> reference);
 
-    <T extends DerAttr> List<T> findAll(Class<T> reference);
+    <T extends DerAttr<?>> List<T> findAll(Class<T> reference);
 
-    <T extends DerAttr> T save(T derAttr);
+    <T extends DerAttr<?>> T save(T derAttr);
 
-    <T extends DerAttr> void delete(Long key, Class<T> reference);
+    <T extends DerAttr<?>> void delete(Long key, Class<T> reference);
 
-    <T extends DerAttr> void delete(T derAttr);
+    <T extends DerAttr<?>> void delete(T derAttr);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
index 6c959aa..d943b83 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
@@ -19,19 +19,18 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 
 public interface DerSchemaDAO extends DAO<DerSchema, String> {
 
-    <T extends DerSchema> T find(String name, Class<T> reference);
+    DerSchema find(String name);
 
-    <T extends DerSchema> List<T> findAll(Class<T> reference);
+    List<DerSchema> findAll();
 
-    <T extends DerAttr> List<T> findAttrs(DerSchema schema, Class<T> reference);
+    <T extends DerAttr<?>> List<T> findAttrs(DerSchema schema, Class<T> reference);
 
-    <T extends DerSchema> T save(T derSchema);
+    DerSchema save(DerSchema derSchema);
 
-    void delete(String name, AttributableUtils attributableUtil);
+    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
index 01f4f63..a72937c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/ExternalResourceDAO.java
@@ -21,8 +21,7 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 
 public interface ExternalResourceDAO extends DAO<ExternalResource, String> {
@@ -39,8 +38,7 @@ public interface ExternalResourceDAO extends DAO<ExternalResource, String> {
 
     ExternalResource save(ExternalResource resource);
 
-    <T extends MappingItem> void deleteMapping(
-            String schemaName, IntMappingType intMappingType, Class<T> reference);
+    void deleteMapping(String schemaName, IntMappingType intMappingType);
 
     void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
index bcdd1ca..f77d9b5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
@@ -20,21 +20,14 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-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.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+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.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
-public interface GroupDAO extends SubjectDAO<GPlainAttr, GDerAttr, GVirAttr> {
-
-    Group find(Long key);
+public interface GroupDAO extends AnyDAO<Group> {
 
     Group find(String name);
 
@@ -42,37 +35,29 @@ public interface GroupDAO extends SubjectDAO<GPlainAttr, GDerAttr, GVirAttr> {
 
     List<Group> findOwnedByGroup(Long groupKey);
 
-    List<Group> findByAttrValue(String schemaName, GPlainAttrValue attrValue);
-
-    List<Group> findByDerAttrValue(String schemaName, String value);
-
-    Group findByAttrUniqueValue(String schemaName, GPlainAttrValue attrUniqueValue);
-
-    List<Group> findByResource(ExternalResource resource);
-
-    List<Group> findAll(Set<String> adminRealms, int page, int itemsPerPage);
-
-    List<Group> findAll(Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
-
-    List<Membership> findMemberships(Group group);
-
-    int count(Set<String> adminRealms);
+    List<AMembership> findAMemberships(Group group);
 
-    Group save(Group group);
+    List<UMembership> findUMemberships(Group group);
 
-    void delete(Group group);
-
-    void delete(Long key);
-
-    Group authFetch(Long key);
+    /**
+     * Finds any objects having resources assigned exclusively because of memberships of the given group.
+     *
+     * @param groupKey group key
+     * @return map containing pairs with any object key and operations to be performed on those resources (DELETE,
+     * typically).
+     */
+    Map<Long, PropagationByResource> findAnyObjectsWithTransitiveResources(Long groupKey);
 
     /**
      * Finds users having resources assigned exclusively because of memberships of the given group.
      *
      * @param groupKey group key
-     * @return map containing pairs with user key and operations to be performed on those resources (DELETE, typically).
+     * @return map containing pairs with user key and operations to be performed on those resources (DELETE,
+     * typically).
      */
-    Map<Long, PropagationByResource> findUsersWithIndirectResources(Long groupKey);
+    Map<Long, PropagationByResource> findUsersWithTransitiveResources(Long groupKey);
+
+    void refreshDynMemberships(AnyObject anyObject);
 
     void refreshDynMemberships(User user);
 


[03/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutePanel.java
----------------------------------------------------------------------
diff --git a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutePanel.java b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutePanel.java
index eb3effe..005e23f 100644
--- a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutePanel.java
+++ b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/panels/CamelRoutePanel.java
@@ -26,8 +26,8 @@ import org.apache.syncope.client.console.annotations.ExtensionPanel;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.rest.CamelRouteRestClient;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
@@ -85,32 +85,33 @@ public class CamelRoutePanel extends AbstractExtensionPanel {
                     final IModel<CamelRouteTO> model) {
 
                 // Uncomment with something similar once SYNCOPE-156 is completed
-                /*final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageref);
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-
-                        editCamelRouteWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new CamelRouteModalPage(pageref, editCamelRouteWin,
-                                        restClient.read(model.getObject().getKey()), false);
-                            }
-
-                        });
-
-                        editCamelRouteWin.show(target);
-                    }
-                }, ActionLink.ActionType.EDIT, "CamelRoutes");
-
-                cellItem.add(panel);*/
+                /* final ActionLinksPanel panel = new
+                 * ActionLinksPanel(componentId, model, pageref);
+                 *
+                 * panel.add(new ActionLink() {
+                 *
+                 * private static final long serialVersionUID = -3722207913631435501L;
+                 *
+                 * @Override
+                 * public void onClick(final AjaxRequestTarget target) {
+                 *
+                 * editCamelRouteWin.setPageCreator(new ModalWindow.PageCreator() {
+                 *
+                 * private static final long serialVersionUID = -7834632442532690940L;
+                 *
+                 * @Override
+                 * public Page createPage() {
+                 * return new CamelRouteModalPage(pageref, editCamelRouteWin,
+                 * restClient.read(model.getObject().getKey()), false);
+                 * }
+                 *
+                 * });
+                 *
+                 * editCamelRouteWin.show(target);
+                 * }
+                 * }, ActionLink.ActionType.EDIT, "CamelRoutes");
+                 *
+                 * cellItem.add(panel); */
             }
         });
 
@@ -138,11 +139,11 @@ public class CamelRoutePanel extends AbstractExtensionPanel {
         @Override
         public Iterator<? extends CamelRouteTO> iterator(final long first, final long count) {
             List<CamelRouteTO> list = new ArrayList<>();
-            if (restClient.isCamelEnabledFor(SubjectType.USER)) {
-                list.addAll(restClient.list(SubjectType.USER));
+            if (restClient.isCamelEnabledFor(AnyTypeKind.USER)) {
+                list.addAll(restClient.list(AnyTypeKind.USER));
             }
-            if (restClient.isCamelEnabledFor(SubjectType.GROUP)) {
-                list.addAll(restClient.list(SubjectType.GROUP));
+            if (restClient.isCamelEnabledFor(AnyTypeKind.GROUP)) {
+                list.addAll(restClient.list(AnyTypeKind.GROUP));
             }
 
             Collections.sort(list, comparator);
@@ -152,11 +153,11 @@ public class CamelRoutePanel extends AbstractExtensionPanel {
 
         @Override
         public long size() {
-            return (restClient.isCamelEnabledFor(SubjectType.USER)
-                    ? restClient.list(SubjectType.USER).size()
+            return (restClient.isCamelEnabledFor(AnyTypeKind.USER)
+                    ? restClient.list(AnyTypeKind.USER).size()
                     : 0)
-                    + (restClient.isCamelEnabledFor(SubjectType.GROUP)
-                            ? restClient.list(SubjectType.GROUP).size()
+                    + (restClient.isCamelEnabledFor(AnyTypeKind.GROUP)
+                            ? restClient.list(AnyTypeKind.GROUP).size()
                             : 0);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/rest/CamelRouteRestClient.java
----------------------------------------------------------------------
diff --git a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/rest/CamelRouteRestClient.java b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/rest/CamelRouteRestClient.java
index f742abb..a4e3a5d 100644
--- a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/rest/CamelRouteRestClient.java
+++ b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/rest/CamelRouteRestClient.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.rest;
 import java.util.List;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
 import org.springframework.stereotype.Component;
 
@@ -30,8 +30,8 @@ public class CamelRouteRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -2018208424159468912L;
 
-    public List<CamelRouteTO> list(final SubjectType subject) {
-        return getService(CamelRouteService.class).list(subject);
+    public List<CamelRouteTO> list(final AnyTypeKind anyTypeKind) {
+        return getService(CamelRouteService.class).list(anyTypeKind);
     }
 
     public CamelRouteTO read(final String key) {
@@ -44,10 +44,15 @@ public class CamelRouteRestClient extends BaseRestClient {
         getService(CamelRouteService.class).update(key, routeTO);
     }
 
-    public boolean isCamelEnabledFor(final SubjectType subjectType) {
-        return subjectType == SubjectType.USER
-                ? SyncopeConsoleSession.get().getSyncopeTO().getUserProvisioningManager().contains("Camel")
-                : SyncopeConsoleSession.get().getSyncopeTO().getGroupProvisioningManager().contains("Camel");
+    public boolean isCamelEnabledFor(final AnyTypeKind anyTypeKind) {
+        return anyTypeKind == AnyTypeKind.USER
+                ? SyncopeConsoleSession.get().getSyncopeTO().
+                getUserProvisioningManager().contains("Camel")
+                : anyTypeKind == AnyTypeKind.ANY_OBJECT
+                        ? SyncopeConsoleSession.get().getSyncopeTO().
+                        getAnyObjectProvisioningManager().contains("Camel")
+                        : SyncopeConsoleSession.get().getSyncopeTO().
+                        getGroupProvisioningManager().contains("Camel");
 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/common-lib/src/main/java/org/apache/syncope/common/lib/to/CamelRouteTO.java
----------------------------------------------------------------------
diff --git a/ext/camel/common-lib/src/main/java/org/apache/syncope/common/lib/to/CamelRouteTO.java b/ext/camel/common-lib/src/main/java/org/apache/syncope/common/lib/to/CamelRouteTO.java
index 5572336..7148de1 100644
--- a/ext/camel/common-lib/src/main/java/org/apache/syncope/common/lib/to/CamelRouteTO.java
+++ b/ext/camel/common-lib/src/main/java/org/apache/syncope/common/lib/to/CamelRouteTO.java
@@ -21,15 +21,17 @@ package org.apache.syncope.common.lib.to;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "camelRoute")
 @XmlType
 public class CamelRouteTO extends AbstractBaseBean {
 
+    private static final long serialVersionUID = 6431992877435181674L;
+
     private String name;
 
-    private SubjectType subjectType;
+    private AnyTypeKind anyTypeKind;
 
     private String content;
 
@@ -49,12 +51,12 @@ public class CamelRouteTO extends AbstractBaseBean {
         this.content = content;
     }
 
-    public SubjectType getSubjectType() {
-        return subjectType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
-    public void setSubjectType(final SubjectType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java
index 19437ab..ec25e29 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/CamelRouteLogic.java
@@ -23,8 +23,8 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
@@ -49,10 +49,10 @@ public class CamelRouteLogic extends AbstractTransactionalLogic<CamelRouteTO> {
 
     @PreAuthorize("hasRole('" + Entitlement.ROUTE_LIST + "')")
     @Transactional(readOnly = true)
-    public List<CamelRouteTO> list(final SubjectType subjectType) {
+    public List<CamelRouteTO> list(final AnyTypeKind anyTypeKind) {
         List<CamelRouteTO> routes = new ArrayList<>();
 
-        for (CamelRoute route : routeDAO.find(subjectType)) {
+        for (CamelRoute route : routeDAO.find(anyTypeKind)) {
             routes.add(binder.getRouteTO(route));
         }
         return routes;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index 8134eb0..e13018f 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -22,7 +22,7 @@ import java.io.StringWriter;
 import java.util.List;
 import java.util.Map;
 import javax.sql.DataSource;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.entity.CamelEntityFactory;
@@ -73,17 +73,18 @@ public class CamelRouteLoader implements SyncopeLoader {
     public void load() {
         synchronized (this) {
             if (!loaded) {
-                loadRoutes(userRoutesLoader.getResource(), SubjectType.USER);
-                loadRoutes(groupRoutesLoader.getResource(), SubjectType.GROUP);
+                loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
+                loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
+                loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
                 loaded = true;
             }
         }
     }
 
-    private boolean loadRoutesFor(final SubjectType subject) {
+    private boolean loadRoutesFor(final AnyTypeKind anyTypeKind) {
         final String sql = String.format("SELECT * FROM %s WHERE SUBJECTTYPE = ?", CamelRoute.class.getSimpleName());
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-        final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { subject.name() });
+        final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { anyTypeKind.name() });
         return rows.isEmpty();
     }
 
@@ -101,8 +102,8 @@ public class CamelRouteLoader implements SyncopeLoader {
         return writer.toString();
     }
 
-    private void loadRoutes(final Resource resource, final SubjectType subjectType) {
-        if (loadRoutesFor(subjectType)) {
+    private void loadRoutes(final Resource resource, final AnyTypeKind anyTypeKind) {
+        if (loadRoutesFor(anyTypeKind)) {
             String query = String.format("INSERT INTO %s(NAME, SUBJECTTYPE, CONTENT) VALUES (?, ?, ?)",
                     CamelRoute.class.getSimpleName());
             JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@@ -122,11 +123,11 @@ public class CamelRouteLoader implements SyncopeLoader {
                     String routeId = ((Element) routeElement).getAttribute("id");
 
                     CamelRoute route = entityFactory.newCamelRoute();
-                    route.setSubjectType(subjectType);
+                    route.setAnyTypeKind(anyTypeKind);
                     route.setKey(routeId);
                     route.setContent(routeContent);
 
-                    jdbcTemplate.update(query, new Object[] { routeId, subjectType.name(), routeContent });
+                    jdbcTemplate.update(query, new Object[] { routeId, anyTypeKind.name(), routeContent });
                     LOG.info("Route successfully loaded: {}", routeId);
                 }
             } catch (DataAccessException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/CamelRouteDAO.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/CamelRouteDAO.java b/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/CamelRouteDAO.java
index cbafcb4..8162bde 100644
--- a/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/CamelRouteDAO.java
+++ b/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/CamelRouteDAO.java
@@ -19,14 +19,14 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
 
 public interface CamelRouteDAO extends DAO<CamelRoute, String> {
 
     CamelRoute find(String key);
 
-    List<CamelRoute> find(SubjectType subjectType);
+    List<CamelRoute> find(AnyTypeKind anyTypeKind);
 
     List<CamelRoute> findAll();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/CamelRoute.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/CamelRoute.java b/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/CamelRoute.java
index ef01fbd..5e25c68 100644
--- a/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/CamelRoute.java
+++ b/ext/camel/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/CamelRoute.java
@@ -18,17 +18,18 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 public interface CamelRoute extends Entity<String> {
 
-    String getContent();
+    void setKey(String name);
 
-    SubjectType getSubjectType();
+    AnyTypeKind getAnyTypeKind();
 
-    void setKey(String name);
+    void setAnyTypeKind(AnyTypeKind anyTypeKind);
+
+    String getContent();
 
     void setContent(String routeContent);
 
-    void setSubjectType(SubjectType subject);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
index 6137015..e9f2c72 100644
--- a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
+++ b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
 import org.apache.syncope.core.persistence.jpa.entity.JPACamelRoute;
@@ -37,11 +37,11 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
 
     @Transactional(readOnly = true)
     @Override
-    public List<CamelRoute> find(final SubjectType subjectType) {
+    public List<CamelRoute> find(final AnyTypeKind anyTypeKind) {
         TypedQuery<CamelRoute> query = entityManager.createQuery(
                 "SELECT e FROM " + JPACamelRoute.class.getSimpleName()
-                + " e WHERE e.subjectType = :subjectType", CamelRoute.class);
-        query.setParameter("subjectType", subjectType);
+                + " e WHERE e.anyTypeKind = :anyTypeKind", CamelRoute.class);
+        query.setParameter("anyTypeKind", anyTypeKind);
 
         return query.getResultList();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPACamelRoute.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPACamelRoute.java b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPACamelRoute.java
index 38803e5..b4ab959 100644
--- a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPACamelRoute.java
+++ b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPACamelRoute.java
@@ -25,7 +25,7 @@ import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
 
 @Entity
@@ -41,7 +41,7 @@ public class JPACamelRoute extends AbstractEntity<String> implements CamelRoute
 
     @NotNull
     @Enumerated(EnumType.STRING)
-    private SubjectType subjectType;
+    private AnyTypeKind anyTypeKind;
 
     @Lob
     private String content;
@@ -57,13 +57,13 @@ public class JPACamelRoute extends AbstractEntity<String> implements CamelRoute
     }
 
     @Override
-    public SubjectType getSubjectType() {
-        return subjectType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
     @Override
-    public void setSubjectType(final SubjectType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 4c04147..5b20fa1 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -81,18 +81,9 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     public Pair<Long, List<PropagationStatus>> update(final UserMod userMod) {
-        return update(userMod, false);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final boolean removeMemberships) {
         PollingConsumer pollingConsumer = getConsumer("direct:updatePort");
 
-        Map<String, Object> props = new HashMap<>();
-        props.put("removeMemberships", removeMemberships);
-
-        sendMessage("direct:updateUser", userMod, props);
+        sendMessage("direct:updateUser", userMod);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
index 0aca43b..212cccd 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
@@ -68,7 +68,7 @@ public class GroupDeleteProcessor implements Processor {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
             for (Map.Entry<Long, PropagationByResource> entry
-                    : groupDAO.findUsersWithIndirectResources(group.getKey()).entrySet()) {
+                    : groupDAO.findAnyObjectsWithTransitiveResources(group.getKey()).entrySet()) {
 
                 WorkflowResult<Long> wfResult =
                         new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
index f27a113..5b21325 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
@@ -57,7 +57,7 @@ public class GroupDeprovisionProcessor implements Processor {
         Long groupKey = exchange.getIn().getBody(Long.class);
         List<String> resources = exchange.getProperty("resources", List.class);
 
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
 
         Collection<String> noPropResourceNames = CollectionUtils.removeAll(group.getResourceNames(), resources);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
index 9f6804e..791a32a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
@@ -63,7 +63,6 @@ public class UserCreateProcessor implements Processor {
                     created.getPropByRes(),
                     actual.getPassword(),
                     actual.getVirAttrs(),
-                    actual.getMemberships(),
                     excludedResources);
             PropagationReporter propagationReporter =
                     ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
index 031e451..3060569 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -56,7 +56,7 @@ public class UserDeprovisionProcessor implements Processor {
         @SuppressWarnings("unchecked")
         List<String> resources = exchange.getProperty("resources", List.class);
 
-        User user = userDAO.authFetch(userKey);
+        User user = userDAO.authFind(userKey);
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
                 userKey,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
index 84f8a2d..355080b 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
@@ -24,7 +24,6 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
@@ -59,7 +58,6 @@ public class UserUpdateProcessor implements Processor {
     public void process(final Exchange exchange) {
         WorkflowResult<Pair<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
         UserMod actual = exchange.getProperty("actual", UserMod.class);
-        boolean removeMemberships = exchange.getProperty("removeMemberships", boolean.class);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated);
         if (tasks.isEmpty()) {
@@ -68,22 +66,7 @@ public class UserUpdateProcessor implements Processor {
                     updated.getResult().getKey().getKey(),
                     actual.getVirAttrsToRemove(),
                     actual.getVirAttrsToUpdate());
-            // SYNCOPE-501: update only virtual attributes (if any of them changed), password propagation is
-            // not required, take care also of membership virtual attributes
-            boolean addOrUpdateMemberships = false;
-            for (MembershipMod membershipMod : actual.getMembershipsToAdd()) {
-                if (!virtAttrHandler.fillMembershipVirtual(
-                        updated.getResult().getKey().getKey(),
-                        membershipMod.getGroup(),
-                        null,
-                        membershipMod.getVirAttrsToRemove(),
-                        membershipMod.getVirAttrsToUpdate(),
-                        false).isEmpty()) {
-
-                    addOrUpdateMemberships = true;
-                }
-            }
-            tasks.addAll(!propByResVirAttr.isEmpty() || addOrUpdateMemberships || removeMemberships
+            tasks.addAll(!propByResVirAttr.isEmpty()
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CamelRouteService.java
----------------------------------------------------------------------
diff --git a/ext/camel/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CamelRouteService.java b/ext/camel/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CamelRouteService.java
index 3a282b3..5d844df 100644
--- a/ext/camel/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CamelRouteService.java
+++ b/ext/camel/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/CamelRouteService.java
@@ -30,14 +30,14 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @Path("camelRoutes")
 public interface CamelRouteService extends JAXRSService {
 
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<CamelRouteTO> list(@NotNull @MatrixParam("subjectType") SubjectType subjectType);
+    List<CamelRouteTO> list(@NotNull @MatrixParam("anyTypeKind") AnyTypeKind anyTypeKind);
 
     @GET
     @Path("{key}")

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/ext/camel/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CamelRouteServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/camel/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CamelRouteServiceImpl.java b/ext/camel/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CamelRouteServiceImpl.java
index a128e06..6853e2b 100644
--- a/ext/camel/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CamelRouteServiceImpl.java
+++ b/ext/camel/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/CamelRouteServiceImpl.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.rest.cxf.service;
 
 import java.util.List;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
 import org.apache.syncope.core.logic.CamelRouteLogic;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,8 +33,8 @@ public class CamelRouteServiceImpl extends AbstractServiceImpl implements CamelR
     private CamelRouteLogic logic;
 
     @Override
-    public List<CamelRouteTO> list(final SubjectType subjectType) {
-        return logic.list(subjectType);
+    public List<CamelRouteTO> list(final AnyTypeKind anyTypeKind) {
+        return logic.list(anyTypeKind);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.java
index 65f84b8..ec5d437 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.java
@@ -20,21 +20,21 @@ package org.apache.syncope.fit.core.reference;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 
 /**
  * Class for integration tests: transform (by making it double) any attribute value for defined schema.
  */
-public class DoubleValueAttributableTransformer implements AttributableTransformer {
+public class DoubleValueAttributableTransformer implements AnyTransformer {
 
     private static final String NAME = "makeItDouble";
 
     @Override
-    public <T extends AbstractAttributableTO> T transform(final T input) {
+    public <T extends AnyTO> T transform(final T input) {
         for (AttrTO attr : input.getPlainAttrs()) {
             if (NAME.equals(attr.getSchema())) {
                 List<String> values = new ArrayList<>(attr.getValues().size());
@@ -54,7 +54,7 @@ public class DoubleValueAttributableTransformer implements AttributableTransform
     }
 
     @Override
-    public <T extends AbstractAttributableMod> T transform(final T input) {
+    public <T extends AnyMod> T transform(final T input) {
         for (AttrMod attr : input.getPlainAttrsToUpdate()) {
             if (NAME.equals(attr.getSchema())) {
                 List<String> values = new ArrayList<>(attr.getValuesToBeAdded().size());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
index bc4d407..9e37c09 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
@@ -19,9 +19,9 @@
 package org.apache.syncope.fit.core.reference;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
@@ -38,7 +38,7 @@ public class TestSyncActions extends DefaultSyncActions {
     private int counter = 0;
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+    public <T extends AnyTO> SyncDelta beforeProvision(
             final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
             throws JobExecutionException {
 
@@ -61,7 +61,7 @@ public class TestSyncActions extends DefaultSyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeAssign(
+    public <T extends AnyTO> SyncDelta beforeAssign(
             final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
             throws JobExecutionException {
 
@@ -73,7 +73,7 @@ public class TestSyncActions extends DefaultSyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
             final T subject,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
index 07882b4..3984c5e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
@@ -45,7 +45,6 @@ import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -292,10 +291,8 @@ public abstract class AbstractITCase {
     }
 
     @SuppressWarnings("unchecked")
-    protected <T extends AbstractSchemaTO> T createSchema(final AttributableType kind,
-            final SchemaType type, final T schemaTO) {
-
-        Response response = schemaService.create(kind, type, schemaTO);
+    protected <T extends AbstractSchemaTO> T createSchema(final SchemaType type, final T schemaTO) {
+        Response response = schemaService.create(type, schemaTO);
         if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
             Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
             if (ex != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index 953d437..019c1c8 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -46,7 +46,6 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
 import org.apache.syncope.common.lib.to.WorkflowFormTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
@@ -130,7 +129,7 @@ public class AuthenticationITCase extends AbstractITCase {
         schemaTO.setMandatoryCondition("false");
         schemaTO.setType(AttrSchemaType.String);
 
-        PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertEquals(schemaTO, newPlainSchemaTO);
 
         // 2. create an user with the role created above (as admin)
@@ -141,18 +140,18 @@ public class AuthenticationITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         // 3. read the schema created above (as admin) - success
-        schemaTO = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+        schemaTO = schemaService.read(SchemaType.PLAIN, schemaName);
         assertNotNull(schemaTO);
 
         // 4. read the schema created above (as user) - success
         SchemaService schemaService2 = clientFactory.create(userTO.getUsername(), "password123").
                 getService(SchemaService.class);
-        schemaTO = schemaService2.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+        schemaTO = schemaService2.read(SchemaType.PLAIN, schemaName);
         assertNotNull(schemaTO);
 
         // 5. update the schema create above (as user) - failure
         try {
-            schemaService2.update(AttributableType.GROUP, SchemaType.PLAIN, schemaName, schemaTO);
+            schemaService2.update(SchemaType.PLAIN, schemaName, schemaTO);
             fail("Schemaupdate as user should not work");
         } catch (AccessControlException e) {
             // CXF Service will throw this exception
@@ -298,7 +297,7 @@ public class AuthenticationITCase extends AbstractITCase {
         // 1. create user with group 9 (users with group 9 are defined in workflow as subject to approval)
         UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(9L);
+        membershipTO.setRightKey(9L);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
index 4681834..fcb988b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
@@ -27,10 +27,9 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.junit.Assume;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -43,7 +42,7 @@ public class CamelRouteITCase extends AbstractITCase {
     public void userRoutes() {
         Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
 
-        List<CamelRouteTO> userRoutes = camelRouteService.list(SubjectType.USER);
+        List<CamelRouteTO> userRoutes = camelRouteService.list(AnyTypeKind.USER);
         assertNotNull(userRoutes);
         assertEquals(15, userRoutes.size());
         for (CamelRouteTO route : userRoutes) {
@@ -55,7 +54,7 @@ public class CamelRouteITCase extends AbstractITCase {
     public void groupRoutes() {
         Assume.assumeTrue(CamelDetector.isCamelEnabledForGroups(syncopeService));
 
-        List<CamelRouteTO> groupRoutes = camelRouteService.list(SubjectType.GROUP);
+        List<CamelRouteTO> groupRoutes = camelRouteService.list(AnyTypeKind.GROUP);
         assertNotNull(groupRoutes);
         assertEquals(7, groupRoutes.size());
         for (CamelRouteTO route : groupRoutes) {
@@ -146,7 +145,7 @@ public class CamelRouteITCase extends AbstractITCase {
             PlainSchemaTO schemaTO = new PlainSchemaTO();
             schemaTO.setKey("camelAttribute");
             schemaTO.setType(AttrSchemaType.String);
-            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+            createSchema(SchemaType.PLAIN, schemaTO);
 
             UserTO userTO = new UserTO();
             userTO.setRealm(SyncopeConstants.ROOT_REALM);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
index 6ae349c..7c1ca19 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
@@ -42,7 +42,6 @@ import org.apache.syncope.common.lib.to.ConfTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -58,7 +57,7 @@ public class ConfigurationITCase extends AbstractITCase {
         PlainSchemaTO testKey = new PlainSchemaTO();
         testKey.setKey("testKey" + getUUIDString());
         testKey.setType(AttrSchemaType.String);
-        createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, testKey);
+        createSchema(SchemaType.PLAIN, testKey);
 
         AttrTO conf = new AttrTO();
         conf.setSchema(testKey.getKey());
@@ -144,7 +143,7 @@ public class ConfigurationITCase extends AbstractITCase {
         failing.setType(AttrSchemaType.String);
 
         try {
-            createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, failing);
+            createSchema(SchemaType.PLAIN, failing);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -191,19 +190,17 @@ public class ConfigurationITCase extends AbstractITCase {
         PlainSchemaTO membershipKey = new PlainSchemaTO();
         membershipKey.setKey("membershipKey" + getUUIDString());
         membershipKey.setType(AttrSchemaType.String);
-        createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, membershipKey);
+        createSchema(SchemaType.PLAIN, membershipKey);
 
         PlainSchemaTO groupKey = new PlainSchemaTO();
         groupKey.setKey("group"
                 + "Key" + getUUIDString());
         groupKey.setType(AttrSchemaType.String);
-        createSchema(AttributableType.GROUP, SchemaType.PLAIN, groupKey);
+        createSchema(SchemaType.PLAIN, groupKey);
 
         GroupTO groupTO = new GroupTO();
         groupTO.setRealm("/");
         groupTO.setName("aGroup" + getUUIDString());
-        groupTO.getMPlainAttrTemplates().add(membershipKey.getKey());
-        groupTO.getGPlainAttrTemplates().add(groupKey.getKey());
         groupTO = createGroup(groupTO);
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 79aa078..5fcc1e9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -46,7 +46,9 @@ import org.apache.syncope.common.lib.to.ConnPoolConfTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
@@ -54,6 +56,7 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -638,22 +641,27 @@ public class ConnectorITCase extends AbstractITCase {
             resourceTO.setKey(resourceName);
             resourceTO.setConnectorId(connectorTO.getKey());
 
-            conf = new HashSet<ConnConfProperty>();
+            conf = new HashSet<>();
             endpoint.getValues().clear();
             endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
             conf.add(endpoint);
 
             resourceTO.getConnConfProperties().addAll(conf);
 
+            ProvisionTO provisionTO = new ProvisionTO();
+            provisionTO.setAnyType(AnyTypeKind.USER.name());
+            provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+            resourceTO.getProvisions().add(provisionTO);
+
             MappingTO mapping = new MappingTO();
-            resourceTO.setUmapping(mapping);
+            provisionTO.setMapping(mapping);
 
             MappingItemTO mapItem = new MappingItemTO();
             mapItem.setExtAttrName("uid");
             mapItem.setIntAttrName("userId");
             mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
             mapItem.setAccountid(true);
-            mapping.setAccountIdItem(mapItem);
+            mapping.setConnObjectKeyItem(mapItem);
             // ----------------------------------------
 
             // ----------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
index adbcdf7..d06ca77 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
@@ -28,7 +28,6 @@ import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -41,7 +40,7 @@ public class DerSchemaITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        List<DerSchemaTO> derivedSchemas = schemaService.list(AttributableType.USER, SchemaType.DERIVED);
+        List<DerSchemaTO> derivedSchemas = schemaService.list(SchemaType.DERIVED);
         assertFalse(derivedSchemas.isEmpty());
         for (DerSchemaTO derivedSchemaTO : derivedSchemas) {
             assertNotNull(derivedSchemaTO);
@@ -50,8 +49,7 @@ public class DerSchemaITCase extends AbstractITCase {
 
     @Test
     public void read() {
-        DerSchemaTO derivedSchemaTO = schemaService.read(AttributableType.USER, SchemaType.DERIVED,
-                "cn");
+        DerSchemaTO derivedSchemaTO = schemaService.read(SchemaType.DERIVED, "cn");
         assertNotNull(derivedSchemaTO);
     }
 
@@ -61,63 +59,62 @@ public class DerSchemaITCase extends AbstractITCase {
         schema.setKey("derived");
         schema.setExpression("derived_sx + '_' + derived_dx");
 
-        DerSchemaTO actual = createSchema(AttributableType.USER, SchemaType.DERIVED, schema);
+        DerSchemaTO actual = createSchema(SchemaType.DERIVED, schema);
         assertNotNull(actual);
 
-        actual = schemaService.read(AttributableType.USER, SchemaType.DERIVED, actual.getKey());
+        actual = schemaService.read(SchemaType.DERIVED, actual.getKey());
         assertNotNull(actual);
         assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
     }
 
     @Test
     public void delete() {
-        DerSchemaTO schema = schemaService.read(AttributableType.GROUP, SchemaType.DERIVED, "rderiveddata");
+        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "rderiveddata");
         assertNotNull(schema);
 
-        schemaService.delete(AttributableType.GROUP, SchemaType.DERIVED, schema.getKey());
+        schemaService.delete(SchemaType.DERIVED, schema.getKey());
 
         try {
-            schemaService.read(AttributableType.GROUP, SchemaType.DERIVED, "rderiveddata");
+            schemaService.read(SchemaType.DERIVED, "rderiveddata");
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.NotFound, e.getType());
         } finally {
             // Recreate schema to make test re-runnable
-            schema = createSchema(AttributableType.GROUP, SchemaType.DERIVED, schema);
+            schema = createSchema(SchemaType.DERIVED, schema);
             assertNotNull(schema);
         }
     }
 
     @Test
     public void update() {
-        DerSchemaTO schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
-                "mderiveddata");
+        DerSchemaTO schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
         assertNotNull(schema);
         assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
         try {
             schema.setExpression("mderived_sx + '.' + mderived_dx");
 
-            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+            schemaService.update(SchemaType.DERIVED,
                     schema.getKey(), schema);
 
-            schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED, "mderiveddata");
+            schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
             assertNotNull(schema);
             assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
         } finally {
             // Set updated back to make test re-runnable
             schema.setExpression("mderived_sx + '-' + mderived_dx");
-            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+            schemaService.update(SchemaType.DERIVED,
                     schema.getKey(), schema);
         }
     }
 
     @Test
     public void issueSYNCOPE323() {
-        DerSchemaTO actual = schemaService.read(AttributableType.GROUP, SchemaType.DERIVED, "rderiveddata");
+        DerSchemaTO actual = schemaService.read(SchemaType.DERIVED, "rderiveddata");
         assertNotNull(actual);
 
         try {
-            createSchema(AttributableType.GROUP, SchemaType.DERIVED, actual);
+            createSchema(SchemaType.DERIVED, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
@@ -126,7 +123,7 @@ public class DerSchemaITCase extends AbstractITCase {
 
         actual.setKey(null);
         try {
-            createSchema(AttributableType.GROUP, SchemaType.DERIVED, actual);
+            createSchema(SchemaType.DERIVED, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
@@ -141,7 +138,7 @@ public class DerSchemaITCase extends AbstractITCase {
         schema.setExpression("derived_sx + '_' + derived_dx");
 
         try {
-            createSchema(AttributableType.GROUP, SchemaType.DERIVED, schema);
+            createSchema(SchemaType.DERIVED, schema);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
index 6a42f5a..e13e400 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
@@ -31,7 +31,6 @@ import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
@@ -64,7 +63,7 @@ public class ExceptionMapperITCase extends AbstractITCase {
         schemaTO.setKey("unique" + schemaUID);
         schemaTO.setType(AttrSchemaType.String);
         schemaTO.setUniqueConstraint(true);
-        createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        createSchema(SchemaType.PLAIN, schemaTO);
 
         // 2. create an user with mandatory attributes and unique
         UserTO userTO1 = new UserTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index 9be9a28..281fb1a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -51,15 +51,15 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.Preference;
@@ -83,7 +83,6 @@ public class GroupITCase extends AbstractITCase {
     public static GroupTO getSampleTO(final String name) {
         GroupTO groupTO = getBasicSampleTO(name);
 
-        groupTO.getGPlainAttrTemplates().add("icon");
         groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
 
         groupTO.getResources().add(RESOURCE_NAME_LDAP);
@@ -94,7 +93,6 @@ public class GroupITCase extends AbstractITCase {
     @Ignore
     public void create() {
         GroupTO groupTO = getSampleTO("lastGroup");
-        groupTO.getGVirAttrTemplates().add("rvirtualdata");
         groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
         groupTO.setGroupOwner(8L);
 
@@ -109,7 +107,7 @@ public class GroupITCase extends AbstractITCase {
         assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP));
 
         ConnObjectTO connObjectTO =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, groupTO.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
         assertNotNull(connObjectTO);
         assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
 
@@ -199,7 +197,6 @@ public class GroupITCase extends AbstractITCase {
     @Test
     public void update() {
         GroupTO groupTO = getSampleTO("latestGroup" + getUUIDString());
-        groupTO.getGPlainAttrTemplates().add("show");
         groupTO = createGroup(groupTO);
 
         assertEquals(1, groupTO.getPlainAttrs().size());
@@ -219,7 +216,6 @@ public class GroupITCase extends AbstractITCase {
     @Test
     public void updateRemovingVirAttribute() {
         GroupTO groupTO = getBasicSampleTO("withvirtual" + getUUIDString());
-        groupTO.getGVirAttrTemplates().add("rvirtualdata");
         groupTO.getVirAttrs().add(attrTO("rvirtualdata", null));
 
         groupTO = createGroup(groupTO);
@@ -239,7 +235,6 @@ public class GroupITCase extends AbstractITCase {
     @Test
     public void updateRemovingDerAttribute() {
         GroupTO groupTO = getBasicSampleTO("withderived" + getUUIDString());
-        groupTO.getGDerAttrTemplates().add("rderivedschema");
         groupTO.getDerAttrs().add(attrTO("rderivedschema", null));
 
         groupTO = createGroup(groupTO);
@@ -325,7 +320,7 @@ public class GroupITCase extends AbstractITCase {
         GroupTO actual = createGroup(getSampleTO("unlink"));
         assertNotNull(actual);
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
@@ -336,7 +331,7 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(actual);
         assertTrue(actual.getResources().isEmpty());
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
     }
 
     @Test
@@ -348,7 +343,7 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(actual);
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -363,7 +358,7 @@ public class GroupITCase extends AbstractITCase {
         assertFalse(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -375,7 +370,7 @@ public class GroupITCase extends AbstractITCase {
         GroupTO actual = createGroup(getSampleTO("unassign"));
         assertNotNull(actual);
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
@@ -387,7 +382,7 @@ public class GroupITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -403,7 +398,7 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(actual);
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -416,7 +411,7 @@ public class GroupITCase extends AbstractITCase {
 
         actual = groupService.read(actual.getKey());
         assertFalse(actual.getResources().isEmpty());
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
     }
 
     @Test
@@ -424,7 +419,7 @@ public class GroupITCase extends AbstractITCase {
         GroupTO actual = createGroup(getSampleTO("deprovision"));
         assertNotNull(actual);
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
@@ -436,7 +431,7 @@ public class GroupITCase extends AbstractITCase {
         assertFalse(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -452,7 +447,7 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(actual);
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -466,7 +461,7 @@ public class GroupITCase extends AbstractITCase {
         actual = groupService.read(actual.getKey());
         assertTrue(actual.getResources().isEmpty());
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
     }
 
     @Test
@@ -478,7 +473,7 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(actual);
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -492,7 +487,7 @@ public class GroupITCase extends AbstractITCase {
         actual = groupService.read(actual.getKey());
         assertTrue(actual.getResources().isEmpty());
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey()));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
@@ -504,7 +499,7 @@ public class GroupITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
 
         try {
-            resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, actual.getKey());
+            resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey());
             fail();
         } catch (Exception e) {
             assertNotNull(e);
@@ -517,7 +512,7 @@ public class GroupITCase extends AbstractITCase {
         PlainSchemaTO badge = new PlainSchemaTO();
         badge.setKey("badge" + getUUIDString());
         badge.setMandatoryCondition("true");
-        schemaService.create(AttributableType.GROUP, SchemaType.PLAIN, badge);
+        schemaService.create(SchemaType.PLAIN, badge);
 
         // 2. create a group *without* an attribute for that schema: it works
         GroupTO groupTO = getSampleTO("lastGroup");
@@ -530,8 +525,6 @@ public class GroupITCase extends AbstractITCase {
         // failure since no values are provided and it is mandatory
         GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupTO.getKey());
-        groupMod.setModGAttrTemplates(true);
-        groupMod.getGPlainAttrTemplates().add(badge.getKey());
 
         try {
             updateGroup(groupMod);
@@ -598,32 +591,32 @@ public class GroupITCase extends AbstractITCase {
     public void issueSYNCOPE632() {
         GroupTO groupTO = null;
         try {
-            // 1. create new LDAP resource having account id mapped to a derived attribute
+            // 1. create new LDAP resource having ConnObjectKey mapped to a derived attribute
             ResourceTO newLDAP = resourceService.read(RESOURCE_NAME_LDAP);
             newLDAP.setKey("new-ldap");
             newLDAP.setPropagationPrimary(true);
-            MappingItemTO accountId = newLDAP.getGmapping().getAccountIdItem();
-            accountId.setIntMappingType(IntMappingType.GroupDerivedSchema);
-            accountId.setIntAttrName("displayProperty");
-            newLDAP.getGmapping().setAccountIdItem(accountId);
-            newLDAP.getGmapping().setAccountLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
+
+            MappingTO mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).getMapping();
+
+            MappingItemTO connObjectKey = mapping.getConnObjectKeyItem();
+            connObjectKey.setIntMappingType(IntMappingType.GroupDerivedSchema);
+            connObjectKey.setIntAttrName("displayProperty");
+            mapping.setConnObjectKeyItem(connObjectKey);
+            mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
 
             MappingItemTO description = new MappingItemTO();
             description.setIntMappingType(IntMappingType.GroupId);
             description.setExtAttrName("description");
             description.setPurpose(MappingPurpose.BOTH);
-            newLDAP.getGmapping().addItem(description);
+            mapping.add(description);
 
             newLDAP = createResource(newLDAP);
             assertNotNull(newLDAP);
 
             // 2. create a group and give the resource created above
             groupTO = getSampleTO("lastGroup" + getUUIDString());
-            groupTO.getGPlainAttrTemplates().add("icon");
             groupTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
-            groupTO.getGPlainAttrTemplates().add("show");
             groupTO.getPlainAttrs().add(attrTO("show", "true"));
-            groupTO.getGDerAttrTemplates().add("displayProperty");
             groupTO.getDerAttrs().add(attrTO("displayProperty", null));
             groupTO.getResources().clear();
             groupTO.getResources().add("new-ldap");
@@ -682,7 +675,7 @@ public class GroupITCase extends AbstractITCase {
         assertTrue(userService.read(4L).getDynGroups().isEmpty());
 
         GroupTO group = getBasicSampleTO("dynMembership");
-        group.setDynMembershipCond("cool==true");
+        group.setUDynMembershipCond("cool==true");
         group = createGroup(group);
         assertNotNull(group);
 
@@ -690,7 +683,7 @@ public class GroupITCase extends AbstractITCase {
 
         GroupMod mod = new GroupMod();
         mod.setKey(group.getKey());
-        mod.setDynMembershipCond("cool==false");
+        mod.setUDynMembershipCond("cool==false");
         groupService.update(mod.getKey(), mod);
 
         assertTrue(userService.read(4L).getDynGroups().isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
index 012c6ab..2ed8449 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
@@ -27,7 +27,7 @@ import java.text.ParseException;
 import java.util.List;
 import org.apache.syncope.common.lib.to.EventCategoryTO;
 import org.apache.syncope.common.lib.to.LoggerTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
 import org.apache.syncope.common.lib.types.AuditLoggerName;
@@ -168,7 +168,7 @@ public class LoggerITCase extends AbstractITCase {
 
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
-            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
                 if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
                         && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
                     assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
@@ -182,7 +182,7 @@ public class LoggerITCase extends AbstractITCase {
 
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
-            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+            if (AnyTypeKind.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
                 if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
                         && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
                     assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
index 18abb97..c58b7b7 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationITCase.java
@@ -28,6 +28,7 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.TraceLevel;
@@ -44,7 +45,8 @@ public class NotificationITCase extends AbstractITCase {
         notificationTO.setTraceLevel(TraceLevel.SUMMARY);
         notificationTO.getEvents().add("create");
 
-        notificationTO.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
+        notificationTO.getAbouts().put(AnyTypeKind.USER.name(),
+                SyncopeClient.getUserSearchConditionBuilder().
                 is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
 
         notificationTO.setRecipientAttrName("email");
@@ -154,7 +156,7 @@ public class NotificationITCase extends AbstractITCase {
     public void issueSYNCOPE446() {
         NotificationTO notificationTO = buildNotificationTO();
         notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
-        notificationTO.setGroupAbout(
+        notificationTO.getAbouts().put(AnyTypeKind.GROUP.name(),
                 SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
 
         NotificationTO actual = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
index b3ca9ab..3fd0778 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/NotificationTaskITCase.java
@@ -30,6 +30,7 @@ import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.common.rest.api.service.NotificationService;
@@ -109,7 +110,8 @@ public class NotificationTaskITCase extends AbstractTaskITCase {
         notification.setTraceLevel(TraceLevel.FAILURES);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
 
-        notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
+        notification.getAbouts().put(AnyTypeKind.USER.name(),
+                SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
 
         notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
@@ -130,7 +132,7 @@ public class NotificationTaskITCase extends AbstractTaskITCase {
         // 2. create user
         UserTO userTO = UserITCase.getUniqueSampleTO("syncope@syncope.apache.org");
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);


[14/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
deleted file mode 100644
index dc02cf3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
+++ /dev/null
@@ -1,220 +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.membership;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import javax.validation.Valid;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractAttributable;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-
-@Entity
-@Table(name = JPAMembership.TABLE, uniqueConstraints =
-        @UniqueConstraint(columnNames = { "user_id", "group_id" }))
-public class JPAMembership extends AbstractAttributable<MPlainAttr, MDerAttr, MVirAttr> implements Membership {
-
-    private static final long serialVersionUID = 5030106264797289469L;
-
-    public static final String TABLE = "Membership";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAUser user;
-
-    @ManyToOne
-    private JPAGroup group;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMPlainAttr> plainAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMDerAttr> derAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMVirAttr> virAttrs;
-
-    public JPAMembership() {
-        super();
-
-        plainAttrs = new ArrayList<>();
-        derAttrs = new ArrayList<>();
-        virAttrs = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Group getGroup() {
-        return group;
-    }
-
-    @Override
-    public void setGroup(final Group group) {
-        checkType(group, JPAGroup.class);
-        this.group = (JPAGroup) group;
-    }
-
-    @Override
-    public User getUser() {
-        return user;
-    }
-
-    @Override
-    public void setUser(final User user) {
-        checkType(user, JPAUser.class);
-        this.user = (JPAUser) user;
-    }
-
-    @Override
-    public boolean addPlainAttr(final MPlainAttr plainAttr) {
-        checkType(plainAttr, JPAMPlainAttr.class);
-
-        if (getGroup() != null && plainAttr.getSchema() != null) {
-            MPlainAttrTemplate found = CollectionUtils.find(getGroup().getAttrTemplates(MPlainAttrTemplate.class),
-                    new Predicate<MPlainAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final MPlainAttrTemplate template) {
-                            return plainAttr.getSchema().equals(template.getSchema());
-                        }
-
-                    });
-            if (found != null) {
-                plainAttr.setTemplate(found);
-                return plainAttrs.add((JPAMPlainAttr) plainAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either group was not yet set, "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removePlainAttr(final MPlainAttr attr) {
-        checkType(attr, JPAMPlainAttr.class);
-        return plainAttrs.remove((JPAMPlainAttr) attr);
-    }
-
-    @Override
-    public List<? extends MPlainAttr> getPlainAttrs() {
-        return plainAttrs;
-    }
-
-    @Override
-    public boolean addDerAttr(final MDerAttr derAttr) {
-        checkType(derAttr, JPAMDerAttr.class);
-
-        if (getGroup() != null && derAttr.getSchema() != null) {
-            MDerAttrTemplate found = CollectionUtils.find(getGroup().getAttrTemplates(MDerAttrTemplate.class),
-                    new Predicate<MDerAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final MDerAttrTemplate template) {
-                            return derAttr.getSchema().equals(template.getSchema());
-                        }
-
-                    });
-            if (found != null) {
-                derAttr.setTemplate(found);
-                return derAttrs.add((JPAMDerAttr) derAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either group was not yet set, "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removeDerAttr(final MDerAttr derAttr) {
-        checkType(derAttr, JPAMDerAttr.class);
-        return derAttrs.remove((JPAMDerAttr) derAttr);
-    }
-
-    @Override
-    public List<? extends MDerAttr> getDerAttrs() {
-        return derAttrs;
-    }
-
-    @Override
-    public boolean addVirAttr(final MVirAttr virAttr) {
-        checkType(virAttr, JPAMVirAttr.class);
-
-        if (getGroup() != null && virAttr.getSchema() != null) {
-            MVirAttrTemplate found = null;
-            for (MVirAttrTemplate template : getGroup().getAttrTemplates(MVirAttrTemplate.class)) {
-                if (virAttr.getSchema().equals(template.getSchema())) {
-                    found = template;
-                }
-            }
-            if (found != null) {
-                virAttr.setTemplate(found);
-                return virAttrs.add((JPAMVirAttr) virAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removeVirAttr(final MVirAttr virAttr) {
-        checkType(virAttr, JPAMVirAttr.class);
-        return virAttrs.remove((JPAMVirAttr) virAttr);
-    }
-
-    @Override
-    public List<? extends MVirAttr> getVirAttrs() {
-        return virAttrs;
-    }
-
-    @Override
-    public String toString() {
-        return "Membership[" + "id=" + id + ", " + user + ", " + group + ']';
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
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/resource/JPAExternalResource.java
new file mode 100644
index 0000000..b4f7f67
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -0,0 +1,394 @@
+/*
+ * 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.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Basic;
+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.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractAnnotatedEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAccountPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPasswordPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.JPASyncPolicy;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+
+/**
+ * Resource for propagation and synchronization.
+ */
+@Entity
+@Table(name = JPAExternalResource.TABLE)
+@ExternalResourceCheck
+public class JPAExternalResource extends AbstractAnnotatedEntity<String> implements ExternalResource {
+
+    private static final long serialVersionUID = -6937712883512073278L;
+
+    public static final String TABLE = "ExternalResource";
+
+    /**
+     * The resource identifier is the name.
+     */
+    @Id
+    private String name;
+
+    /**
+     * Should this resource enforce the mandatory constraints?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer enforceMandatoryCondition;
+
+    /**
+     * The resource type is identified by the associated connector.
+     */
+    @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
+    @NotNull
+    private JPAConnInstance connector;
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "resource")
+    private List<JPAProvision> provisions = new ArrayList<>();
+
+    /**
+     * Is this resource primary, for propagations?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer propagationPrimary;
+
+    /**
+     * Priority index for propagation ordering.
+     */
+    @Column(nullable = false)
+    private Integer propagationPriority;
+
+    /**
+     * Generate random password for propagation, if not provided?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer randomPwdIfNotProvided;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private PropagationMode propagationMode;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel createTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel updateTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel deleteTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel syncTraceLevel;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAPasswordPolicy passwordPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAccountPolicy accountPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPASyncPolicy syncPolicy;
+
+    /**
+     * Configuration properties that are overridden from the connector instance.
+     */
+    @Lob
+    private String jsonConf;
+
+    /**
+     * (Optional) classes for PropagationAction.
+     */
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "ExternalResource_PropActions",
+            joinColumns =
+            @JoinColumn(name = "resource_name", referencedColumnName = "name"))
+    private List<String> propagationActionsClassNames = new ArrayList<>();
+
+    /**
+     * Default constructor.
+     */
+    public JPAExternalResource() {
+        super();
+
+        enforceMandatoryCondition = getBooleanAsInteger(false);
+        propagationPrimary = 0;
+        propagationPriority = 0;
+        randomPwdIfNotProvided = 0;
+        propagationMode = PropagationMode.TWO_PHASES;
+
+        createTraceLevel = TraceLevel.FAILURES;
+        updateTraceLevel = TraceLevel.FAILURES;
+        deleteTraceLevel = TraceLevel.FAILURES;
+        syncTraceLevel = TraceLevel.FAILURES;
+    }
+
+    @Override
+    public boolean isEnforceMandatoryCondition() {
+        return isBooleanAsInteger(enforceMandatoryCondition);
+    }
+
+    @Override
+    public void setEnforceMandatoryCondition(final boolean enforceMandatoryCondition) {
+        this.enforceMandatoryCondition = getBooleanAsInteger(enforceMandatoryCondition);
+    }
+
+    @Override
+    public ConnInstance getConnector() {
+        return connector;
+    }
+
+    @Override
+    public void setConnector(final ConnInstance connector) {
+        checkType(connector, JPAConnInstance.class);
+        this.connector = (JPAConnInstance) connector;
+    }
+
+    @Override
+    public boolean add(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        return this.provisions.add((JPAProvision) provision);
+    }
+
+    @Override
+    public boolean remove(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        return this.provisions.remove((JPAProvision) provision);
+    }
+
+    @Override
+    public Provision getProvision(final ObjectClass objectClass) {
+        return CollectionUtils.find(provisions, new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return provision.getObjectClass().equals(objectClass);
+            }
+        });
+    }
+
+    @Override
+    public Provision getProvision(final AnyType anyType) {
+        return CollectionUtils.find(provisions, new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return provision.getAnyType().equals(anyType);
+            }
+        });
+    }
+
+    @Override
+    public List<? extends Provision> getProvisions() {
+        return provisions;
+    }
+
+    @Override
+    public boolean isPropagationPrimary() {
+        return isBooleanAsInteger(propagationPrimary);
+    }
+
+    @Override
+    public void setPropagationPrimary(final boolean propagationPrimary) {
+        this.propagationPrimary = getBooleanAsInteger(propagationPrimary);
+    }
+
+    @Override
+    public Integer getPropagationPriority() {
+        return propagationPriority;
+    }
+
+    @Override
+    public void setPropagationPriority(final Integer propagationPriority) {
+        if (propagationPriority != null) {
+            this.propagationPriority = propagationPriority;
+        }
+    }
+
+    @Override
+    public boolean isRandomPwdIfNotProvided() {
+        return isBooleanAsInteger(randomPwdIfNotProvided);
+    }
+
+    @Override
+    public void setRandomPwdIfNotProvided(final boolean randomPwdIfNotProvided) {
+        this.randomPwdIfNotProvided = getBooleanAsInteger(randomPwdIfNotProvided);
+    }
+
+    @Override
+    public PropagationMode getPropagationMode() {
+        return propagationMode;
+    }
+
+    @Override
+    public void setPropagationMode(final PropagationMode propagationMode) {
+        this.propagationMode = propagationMode;
+    }
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public TraceLevel getCreateTraceLevel() {
+        return createTraceLevel;
+    }
+
+    @Override
+    public void setCreateTraceLevel(final TraceLevel createTraceLevel) {
+        this.createTraceLevel = createTraceLevel;
+    }
+
+    @Override
+
+    public TraceLevel getDeleteTraceLevel() {
+        return deleteTraceLevel;
+    }
+
+    @Override
+    public void setDeleteTraceLevel(final TraceLevel deleteTraceLevel) {
+        this.deleteTraceLevel = deleteTraceLevel;
+    }
+
+    @Override
+    public TraceLevel getUpdateTraceLevel() {
+        return updateTraceLevel;
+    }
+
+    @Override
+    public void setUpdateTraceLevel(final TraceLevel updateTraceLevel) {
+        this.updateTraceLevel = updateTraceLevel;
+    }
+
+    @Override
+    public TraceLevel getSyncTraceLevel() {
+        return syncTraceLevel;
+    }
+
+    @Override
+    public void setSyncTraceLevel(final TraceLevel syncTraceLevel) {
+        this.syncTraceLevel = syncTraceLevel;
+    }
+
+    @Override
+    public AccountPolicy getAccountPolicy() {
+        return accountPolicy;
+    }
+
+    @Override
+    public void setAccountPolicy(final AccountPolicy accountPolicy) {
+        checkType(accountPolicy, JPAAccountPolicy.class);
+        this.accountPolicy = (JPAAccountPolicy) accountPolicy;
+    }
+
+    @Override
+    public PasswordPolicy getPasswordPolicy() {
+        return passwordPolicy;
+    }
+
+    @Override
+    public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
+        checkType(passwordPolicy, JPAPasswordPolicy.class);
+        this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
+    }
+
+    @Override
+    public SyncPolicy getSyncPolicy() {
+        return syncPolicy;
+    }
+
+    @Override
+    public void setSyncPolicy(final SyncPolicy syncPolicy) {
+        checkType(syncPolicy, JPASyncPolicy.class);
+        this.syncPolicy = (JPASyncPolicy) syncPolicy;
+    }
+
+    @Override
+    public Set<ConnConfProperty> getConnInstanceConfiguration() {
+        Set<ConnConfProperty> configuration = new HashSet<>();
+        if (!StringUtils.isBlank(jsonConf)) {
+            CollectionUtils.addAll(configuration, POJOHelper.deserialize(jsonConf, ConnConfProperty[].class));
+        }
+
+        return configuration;
+    }
+
+    @Override
+    public void setConnInstanceConfiguration(final Set<ConnConfProperty> properties) {
+        jsonConf = POJOHelper.serialize(new HashSet<>(properties));
+    }
+
+    @Override
+    public List<String> getPropagationActionsClassNames() {
+        return propagationActionsClassNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
new file mode 100644
index 0000000..227f0fd
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -0,0 +1,142 @@
+/*
+ * 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.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.IntMappingType;
+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.AbstractEntity;
+
+@Entity
+@Table(name = JPAMapping.TABLE)
+@Cacheable
+public class JPAMapping extends AbstractEntity<Long> implements Mapping {
+
+    private static final long serialVersionUID = 4316047254916259158L;
+
+    public static final String TABLE = "Mapping";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPAProvision provision;
+
+    /**
+     * Attribute mappings.
+     */
+    @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 Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Provision getProvision() {
+        return provision;
+    }
+
+    @Override
+    public void setProvision(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        this.provision = (JPAProvision) provision;
+    }
+
+    @Override
+    public void setConnObjectKeyItem(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        this.addConnObjectKeyItem((JPAMappingItem) item);
+    }
+
+    @Override
+    public List<? extends MappingItem> getItems() {
+        return items;
+    }
+
+    @Override
+    public boolean add(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        return items.contains((JPAMappingItem) item) || items.add((JPAMappingItem) item);
+    }
+
+    @Override
+    public boolean remove(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        return items.remove((JPAMappingItem) item);
+    }
+
+    @Override
+    public MappingItem getConnObjectKeyItem() {
+        return CollectionUtils.find(getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.isConnObjectKey();
+            }
+        });
+    }
+
+    protected boolean addConnObjectKeyItem(final MappingItem connObjectKeyItem) {
+        if (IntMappingType.UserVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.GroupVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.AnyVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
+
+            throw new IllegalArgumentException("Virtual attributes cannot be set as ConnObjectKey");
+        }
+        if (IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
+            throw new IllegalArgumentException("Password attributes cannot be set as ConnObjectKey");
+        }
+
+        connObjectKeyItem.setExtAttrName(connObjectKeyItem.getExtAttrName());
+        connObjectKeyItem.setConnObjectKey(true);
+
+        return this.add(connObjectKeyItem);
+    }
+
+    @Override
+    public String getConnObjectLink() {
+        return connObjectLink;
+    }
+
+    @Override
+    public void setConnObjectLink(final String connObjectLink) {
+        this.connObjectLink = connObjectLink;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
new file mode 100644
index 0000000..d9c1af2
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.resource;
+
+import javax.persistence.Basic;
+import javax.persistence.Cacheable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+
+@Entity
+@Table(name = JPAMappingItem.TABLE)
+@Cacheable
+public class JPAMappingItem extends AbstractEntity<Long> implements MappingItem {
+
+    private static final long serialVersionUID = 7383601853619332424L;
+
+    public static final String TABLE = "MappingItem";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAMapping mapping;
+
+    @Column(nullable = true)
+    private String intAttrName;
+
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private IntMappingType intMappingType;
+
+    /**
+     * Target resource's field to be mapped.
+     */
+    @Column(nullable = true)
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    @Column(nullable = false)
+    private String mandatoryCondition;
+
+    /**
+     * Specify if the mapped target resource's field is the key.
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer password;
+
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private MappingPurpose purpose;
+
+    public JPAMappingItem() {
+        super();
+
+        mandatoryCondition = Boolean.FALSE.toString();
+
+        connObjectKey = getBooleanAsInteger(false);
+        password = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Mapping getMapping() {
+        return mapping;
+    }
+
+    @Override
+    public void setMapping(final Mapping mapping) {
+        checkType(mapping, JPAMapping.class);
+        this.mapping = (JPAMapping) mapping;
+    }
+
+    @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() {
+        final String name;
+
+        switch (getIntMappingType()) {
+            case UserId:
+            case GroupId:
+            case AnyId:
+                name = "id";
+                break;
+
+            case Username:
+                name = "username";
+                break;
+
+            case Password:
+                name = "password";
+                break;
+
+            case GroupName:
+                name = "groupName";
+                break;
+
+            case GroupOwnerSchema:
+                name = "groupOwnerSchema";
+                break;
+
+            default:
+                name = intAttrName;
+        }
+
+        return name;
+    }
+
+    @Override
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    @Override
+    public IntMappingType getIntMappingType() {
+        return intMappingType;
+    }
+
+    @Override
+    public void setIntMappingType(final IntMappingType intMappingType) {
+        this.intMappingType = intMappingType;
+    }
+
+    @Override
+    public boolean isConnObjectKey() {
+        return isBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = getBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public boolean isPassword() {
+        return isBooleanAsInteger(password);
+    }
+
+    @Override
+    public void setPassword(final boolean password) {
+        this.password = getBooleanAsInteger(password);
+    }
+
+    @Override
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    @Override
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..273b79d
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
@@ -0,0 +1,133 @@
+/*
+ * 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.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+@Entity
+@Table(name = JPAProvision.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "resource_name", "anyType_name" }))
+public class JPAProvision extends AbstractEntity<Long> implements Provision {
+
+    private static final long serialVersionUID = -1807889487945989443L;
+
+    public static final String TABLE = "Provision";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAExternalResource resource;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    private String objectClass;
+
+    @Lob
+    private String serializedSyncToken;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "provision")
+    private JPAMapping mapping;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @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 objectClass == null
+                ? null
+                : new ObjectClass(objectClass);
+    }
+
+    @Override
+    public void setObjectClass(final ObjectClass objectClass) {
+        this.objectClass = objectClass == null ? null : objectClass.getObjectClassValue();
+    }
+
+    @Override
+    public SyncToken getSyncToken() {
+        return serializedSyncToken == null
+                ? null
+                : POJOHelper.deserialize(serializedSyncToken, SyncToken.class);
+    }
+
+    @Override
+    public String getSerializedSyncToken() {
+        return this.serializedSyncToken;
+    }
+
+    @Override
+    public void setSyncToken(final SyncToken syncToken) {
+        this.serializedSyncToken = syncToken == null ? null : POJOHelper.serialize(syncToken);
+    }
+
+    @Override
+    public Mapping getMapping() {
+        return mapping;
+    }
+
+    @Override
+    public void setMapping(final Mapping mapping) {
+        checkType(mapping, JPAMapping.class);
+        this.mapping = (JPAMapping) mapping;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
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 821bbe4..9723f1d 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
@@ -29,10 +29,10 @@ import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ProvisioningTaskCheck;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @MappedSuperclass
 @ProvisioningTaskCheck

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
new file mode 100644
index 0000000..93e10e3
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
@@ -0,0 +1,91 @@
+/*
+ * 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.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+
+@Entity
+@Table(name = JPAAnyFilter.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "pushTask_id", "anyType_name" }))
+public class JPAAnyFilter extends AbstractEntity<Long> implements AnyFilter {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyFilter";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAPushTask pushTask;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String filter;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public PushTask getPushTask() {
+        return pushTask;
+    }
+
+    @Override
+    public void setPushTask(final PushTask syncTask) {
+        checkType(syncTask, JPAPushTask.class);
+        this.pushTask = (JPAPushTask) syncTask;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public String get() {
+        return filter;
+    }
+
+    @Override
+    public void set(final String filter) {
+        this.filter = filter;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
new file mode 100644
index 0000000..d90f605
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+
+@Entity
+@Table(name = JPAAnyTemplate.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "syncTask_id", "anyType_name" }))
+public class JPAAnyTemplate extends AbstractEntity<Long> implements AnyTemplate {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyTemplate";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPASyncTask syncTask;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String template;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public SyncTask getSyncTask() {
+        return syncTask;
+    }
+
+    @Override
+    public void setSyncTask(final SyncTask syncTask) {
+        checkType(syncTask, JPASyncTask.class);
+        this.syncTask = (JPASyncTask) syncTask;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public AnyTO get() {
+        return template == null
+                ? anyType == null
+                        ? null
+                        : new JPAAnyUtilsFactory().getInstance(anyType.getKind()).newAnyTO()
+                : POJOHelper.deserialize(template, AnyTO.class);
+    }
+
+    @Override
+    public void set(final AnyTO template) {
+        if (template == null) {
+            this.template = null;
+        } else {
+            this.template = POJOHelper.serialize(template);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
index b63bd10..be72e1e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
@@ -49,7 +49,7 @@ public class JPANotificationTask extends JPATask implements NotificationTask {
     @Column(name = "address")
     @CollectionTable(name = "NotificationTask_recipients",
             joinColumns =
-            @JoinColumn(name = "NotificationTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "notificationTask_id", referencedColumnName = "id"))
     private Set<String> recipients;
 
     @NotNull

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
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 90104a3..cffc4bf 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
@@ -28,14 +28,14 @@ import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+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.jpa.validation.entity.PropagationTaskCheck;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.identityconnectors.framework.common.objects.Attribute;
 
@@ -62,14 +62,14 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private ResourceOperation propagationOperation;
 
     /**
-     * The accountId on the external resource.
+     * The connObjectKey on the external resource.
      */
-    private String accountId;
+    private String connObjectKey;
 
     /**
-     * The (optional) former accountId on the external resource.
+     * The (optional) former connObjectKey on the external resource.
      */
-    private String oldAccountId;
+    private String oldConnObjectKey;
 
     /**
      * Attributes to be propagated.
@@ -80,9 +80,9 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private String objectClassName;
 
     @Enumerated(EnumType.STRING)
-    private AttributableType subjectType;
+    private AnyTypeKind anyTypeKind;
 
-    private Long subjectId;
+    private Long anyKey;
 
     public JPAPropagationTask() {
         super();
@@ -96,23 +96,23 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private JPAExternalResource resource;
 
     @Override
-    public String getAccountId() {
-        return accountId;
+    public String getConnObjectKey() {
+        return connObjectKey;
     }
 
     @Override
-    public void setAccountId(final String accountId) {
-        this.accountId = accountId;
+    public void setConnObjectKey(final String connObjectKey) {
+        this.connObjectKey = connObjectKey;
     }
 
     @Override
-    public String getOldAccountId() {
-        return oldAccountId;
+    public String getOldConnObjectKey() {
+        return oldConnObjectKey;
     }
 
     @Override
-    public void setOldAccountId(final String oldAccountId) {
-        this.oldAccountId = oldAccountId;
+    public void setOldConnObjectKey(final String oldConnObjectKey) {
+        this.oldConnObjectKey = oldConnObjectKey;
     }
 
     @Override
@@ -176,22 +176,22 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     }
 
     @Override
-    public AttributableType getSubjectType() {
-        return subjectType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
     @Override
-    public void setSubjectType(final AttributableType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
     @Override
-    public Long getSubjectKey() {
-        return subjectId;
+    public Long getAnyKey() {
+        return anyKey;
     }
 
     @Override
-    public void setSubjectKey(final Long subjectKey) {
-        this.subjectId = subjectKey;
+    public void setAnyKey(final Long anyKey) {
+        this.anyKey = anyKey;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index c627dd2..07e6f00 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity.task;
 
 import java.util.ArrayList;
 import java.util.List;
+import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.DiscriminatorValue;
@@ -27,7 +28,12 @@ import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.provisioning.api.job.PushJob;
 
@@ -41,12 +47,11 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     @Column(name = "actionClassName")
     @CollectionTable(name = "PushTask_actionsClassNames",
             joinColumns =
-            @JoinColumn(name = "PushTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "pushTask_id", referencedColumnName = "id"))
     private List<String> actionsClassNames = new ArrayList<>();
 
-    private String userFilter;
-
-    private String groupFilter;
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "pushTask")
+    private List<JPAAnyFilter> filters = new ArrayList<>();
 
     /**
      * Default constructor.
@@ -61,22 +66,30 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     }
 
     @Override
-    public String getUserFilter() {
-        return userFilter;
+    public boolean add(final AnyFilter filter) {
+        checkType(filter, JPAAnyFilter.class);
+        return this.filters.add((JPAAnyFilter) filter);
     }
 
     @Override
-    public void setUserFilter(final String filter) {
-        this.userFilter = filter;
+    public boolean remove(final AnyFilter filter) {
+        checkType(filter, JPAAnyFilter.class);
+        return this.filters.remove((JPAAnyFilter) filter);
     }
 
     @Override
-    public String getGroupFilter() {
-        return groupFilter;
+    public AnyFilter getFilter(final AnyType anyType) {
+        return CollectionUtils.find(filters, new Predicate<AnyFilter>() {
+
+            @Override
+            public boolean evaluate(final AnyFilter filter) {
+                return anyType != null && anyType.equals(filter.getAnyType());
+            }
+        });
     }
 
     @Override
-    public void setGroupFilter(final String filter) {
-        this.groupFilter = filter;
+    public List<? extends AnyFilter> getFilters() {
+        return filters;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index f98074d..0106a65 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity.task;
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.Basic;
+import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.DiscriminatorValue;
@@ -28,17 +29,18 @@ import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 
 @Entity
@@ -54,14 +56,11 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     @Column(name = "actionClassName")
     @CollectionTable(name = "SyncTask_actionsClassNames",
             joinColumns =
-            @JoinColumn(name = "SyncTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "syncTask_id", referencedColumnName = "id"))
     private List<String> actionsClassNames = new ArrayList<>();
 
-    @Lob
-    private String userTemplate;
-
-    @Lob
-    private String groupTemplate;
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
+    private List<JPAAnyTemplate> templates = new ArrayList<>();
 
     @Basic
     @Min(0)
@@ -92,36 +91,41 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public UserTO getUserTemplate() {
-        return userTemplate == null
-                ? new UserTO()
-                : POJOHelper.deserialize(userTemplate, UserTO.class);
+    public boolean isFullReconciliation() {
+        return isBooleanAsInteger(fullReconciliation);
     }
 
     @Override
-    public void setUserTemplate(final UserTO userTemplate) {
-        this.userTemplate = POJOHelper.serialize(userTemplate);
+    public void setFullReconciliation(final boolean fullReconciliation) {
+        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
     }
 
     @Override
-    public GroupTO getGroupTemplate() {
-        return userTemplate == null
-                ? new GroupTO()
-                : POJOHelper.deserialize(groupTemplate, GroupTO.class);
+    public boolean add(final AnyTemplate template) {
+        checkType(template, JPAAnyTemplate.class);
+        return this.templates.add((JPAAnyTemplate) template);
     }
 
     @Override
-    public void setGroupTemplate(final GroupTO groupTemplate) {
-        this.groupTemplate = POJOHelper.serialize(groupTemplate);
+    public boolean remove(final AnyTemplate template) {
+        checkType(template, JPAAnyTemplate.class);
+        return this.templates.remove((JPAAnyTemplate) template);
     }
 
     @Override
-    public boolean isFullReconciliation() {
-        return isBooleanAsInteger(fullReconciliation);
+    public AnyTemplate getTemplate(final AnyType anyType) {
+        return CollectionUtils.find(templates, new Predicate<AnyTemplate>() {
+
+            @Override
+            public boolean evaluate(final AnyTemplate template) {
+                return anyType != null && anyType.equals(template.getAnyType());
+            }
+        });
     }
 
     @Override
-    public void setFullReconciliation(final boolean fullReconciliation) {
-        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
+    public List<? extends AnyTemplate> getTemplates() {
+        return templates;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
new file mode 100644
index 0000000..00e85c4
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
@@ -0,0 +1,50 @@
+/*
+ * 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.user;
+
+import java.util.List;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.core.persistence.api.entity.user.UDynMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractDynMembership;
+
+@MappedSuperclass
+public abstract class AbstractUDynMembership extends AbstractDynMembership<User> implements UDynMembership {
+
+    private static final long serialVersionUID = 6296230283800203205L;
+
+    protected abstract List<JPAUser> internalGetUsers();
+
+    @Override
+    public boolean add(final User user) {
+        checkType(user, JPAUser.class);
+        return internalGetUsers().add((JPAUser) user);
+    }
+
+    @Override
+    public boolean remove(final User user) {
+        checkType(user, JPAUser.class);
+        return internalGetUsers().remove((JPAUser) user);
+    }
+
+    @Override
+    public List<? extends User> getMembers() {
+        return internalGetUsers();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
new file mode 100644
index 0000000..f812b28
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
@@ -0,0 +1,76 @@
+/*
+ * 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.user;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.jpa.entity.JPARole;
+
+@Entity
+@Table(name = JPADynRoleMembership.TABLE)
+public class JPADynRoleMembership extends AbstractUDynMembership implements DynRoleMembership {
+
+    private static final long serialVersionUID = -7336814163949640354L;
+
+    public static final String TABLE = "DynRoleMembership";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPARole role;
+
+    @ManyToMany
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "dynRoleMembership_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "user_id"))
+    private List<JPAUser> users = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    protected List<JPAUser> internalGetUsers() {
+        return users;
+    }
+
+    @Override
+    public Role getRole() {
+        return role;
+    }
+
+    @Override
+    public void setRole(final Role role) {
+        checkType(role, JPARole.class);
+        this.role = (JPARole) role;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
index b9cfb2c..90bee1b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
@@ -19,19 +19,15 @@
 package org.apache.syncope.core.persistence.jpa.entity.user;
 
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
 
 @Entity
 @Table(name = JPAUDerAttr.TABLE)
-public class JPAUDerAttr extends AbstractDerAttr implements UDerAttr {
+public class JPAUDerAttr extends AbstractDerAttr<User> implements UDerAttr {
 
     private static final long serialVersionUID = 4723044452807292060L;
 
@@ -40,28 +36,15 @@ public class JPAUDerAttr extends AbstractDerAttr implements UDerAttr {
     @ManyToOne
     private JPAUser owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAUDerSchema derSchema;
-
     @Override
     public User getOwner() {
         return owner;
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final User owner) {
         checkType(owner, JPAUser.class);
         this.owner = (JPAUser) owner;
     }
 
-    @Override
-    public UDerSchema getSchema() {
-        return derSchema;
-    }
-
-    @Override
-    public void setSchema(final DerSchema derSchema) {
-        checkType(derSchema, JPAUDerSchema.class);
-        this.derSchema = (JPAUDerSchema) derSchema;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
deleted file mode 100644
index eb9ae93..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
+++ /dev/null
@@ -1,34 +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.user;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-
-@Entity
-@Table(name = JPAUDerSchema.TABLE)
-public class JPAUDerSchema extends AbstractDerSchema implements UDerSchema {
-
-    private static final long serialVersionUID = 6244467775394201229L;
-
-    public static final String TABLE = "UDerSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
new file mode 100644
index 0000000..ac150dc
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
@@ -0,0 +1,76 @@
+/*
+ * 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.user;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAUDynGroupMembership.TABLE)
+public class JPAUDynGroupMembership extends AbstractUDynMembership implements UDynGroupMembership {
+
+    private static final long serialVersionUID = -7336814163949640354L;
+
+    public static final String TABLE = "UDynGroupMembership";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPAGroup group;
+
+    @ManyToMany
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "uDynGroupMembership_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "user_id"))
+    private List<JPAUser> users = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    protected List<JPAUser> internalGetUsers() {
+        return users;
+    }
+
+    @Override
+    public Group getGroup() {
+        return group;
+    }
+
+    @Override
+    public void setGroup(final Group role) {
+        checkType(role, JPAGroup.class);
+        this.group = (JPAGroup) role;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
deleted file mode 100644
index 86b349a..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
+++ /dev/null
@@ -1,125 +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.user;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMapping;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-
-@Entity
-@Table(name = JPAUMapping.TABLE)
-public class JPAUMapping extends AbstractMapping<UMappingItem> implements UMapping {
-
-    private static final long serialVersionUID = 4285801404504561073L;
-
-    public static final String TABLE = "UMapping";
-
-    @Id
-    private Long id;
-
-    /**
-     * Resource owning this mapping.
-     */
-    @OneToOne
-    private JPAExternalResource resource;
-
-    /**
-     * Attribute mappings.
-     */
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
-    private List<JPAUMappingItem> items;
-
-    public JPAUMapping() {
-        super();
-
-        items = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public ExternalResource getResource() {
-        return resource;
-    }
-
-    @Override
-    public void setResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        this.resource = (JPAExternalResource) resource;
-    }
-
-    @Override
-    public void setAccountIdItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        this.addAccountIdItem((JPAUMappingItem) item);
-    }
-
-    @Override
-    public UMappingItem getPasswordItem() {
-        UMappingItem passwordItem = null;
-        for (MappingItem item : getItems()) {
-            if (item.isPassword()) {
-                passwordItem = (JPAUMappingItem) item;
-            }
-        }
-        return passwordItem;
-    }
-
-    @Override
-    public boolean setPasswordItem(final UMappingItem passwordItem) {
-        checkType(passwordItem, JPAUMappingItem.class);
-
-        passwordItem.setExtAttrName(OperationalAttributes.PASSWORD_NAME);
-        passwordItem.setPassword(true);
-        return this.addItem((JPAUMappingItem) passwordItem);
-    }
-
-    @Override
-    public List<? extends UMappingItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean addItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        return items.contains((JPAUMappingItem) item) || items.add((JPAUMappingItem) item);
-    }
-
-    @Override
-    public boolean removeItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        return items.remove((JPAUMappingItem) item);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
deleted file mode 100644
index 14b94f0..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.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.jpa.entity.user;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
-
-@Entity
-@Table(name = JPAUMappingItem.TABLE)
-public class JPAUMappingItem extends AbstractMappingItem implements UMappingItem {
-
-    private static final long serialVersionUID = 2936446317887310833L;
-
-    public static final String TABLE = "UMappingItem";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAUMapping mapping;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Mapping<UMappingItem> getMapping() {
-        return mapping;
-    }
-
-    @Override
-    public void setMapping(final Mapping<?> mapping) {
-        checkType(mapping, JPAUMapping.class);
-        this.mapping = (JPAUMapping) mapping;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
new file mode 100644
index 0000000..dd79434
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
@@ -0,0 +1,77 @@
+/*
+ * 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.user;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAUMembership.TABLE)
+public class JPAUMembership extends AbstractEntity<Long> implements UMembership {
+
+    private static final long serialVersionUID = -14584450896965100L;
+
+    public static final String TABLE = "UMembership";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @Column(name = "user_id")
+    private JPAUser leftEnd;
+
+    @ManyToOne
+    @Column(name = "group_id")
+    private JPAGroup rightEnd;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public JPAUser getLeftEnd() {
+        return leftEnd;
+    }
+
+    @Override
+    public void setLeftEnd(final User leftEnd) {
+        checkType(leftEnd, JPAUser.class);
+        this.leftEnd = (JPAUser) leftEnd;
+    }
+
+    @Override
+    public JPAGroup getRightEnd() {
+        return rightEnd;
+    }
+
+    @Override
+    public void setRightEnd(final Group rightEnd) {
+        checkType(rightEnd, JPAGroup.class);
+        this.rightEnd = (JPAGroup) rightEnd;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
index 8c2e06a..56898d4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
@@ -24,26 +24,22 @@ import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.Valid;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 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.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
 
 @Entity
 @Table(name = JPAUPlainAttr.TABLE)
-public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
+public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr {
 
     private static final long serialVersionUID = 6333601983691157406L;
 
@@ -62,18 +58,11 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     private JPAUser owner;
 
     /**
-     * The schema of this attribute.
-     */
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = "schema_name")
-    private JPAUPlainSchema schema;
-
-    /**
      * Values of this attribute (if schema is not UNIQUE).
      */
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
-    private List<JPAUPlainAttrValue> values;
+    private List<JPAUPlainAttrValue> values = new ArrayList<>();
 
     /**
      * Value of this attribute (if schema is UNIQUE).
@@ -82,14 +71,6 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     @Valid
     private JPAUPlainAttrUniqueValue uniqueValue;
 
-    /**
-     * Default constructor.
-     */
-    public JPAUPlainAttr() {
-        super();
-        values = new ArrayList<>();
-    }
-
     @Override
     public Long getKey() {
         return id;
@@ -101,30 +82,19 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final User owner) {
         checkType(owner, JPAUser.class);
         this.owner = (JPAUser) owner;
     }
 
     @Override
-    public UPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPAUPlainSchema.class);
-        this.schema = (JPAUPlainSchema) schema;
-    }
-
-    @Override
-    protected boolean addValue(final PlainAttrValue attrValue) {
+    protected boolean addForMultiValue(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAUPlainAttrValue.class);
         return values.add((JPAUPlainAttrValue) attrValue);
     }
 
     @Override
-    public boolean removeValue(final PlainAttrValue attrValue) {
+    public boolean remove(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAUPlainAttrValue.class);
         return values.remove((JPAUPlainAttrValue) attrValue);
     }


[23/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/MembershipDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/MembershipDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/MembershipDAO.java
deleted file mode 100644
index 964e0e8..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/MembershipDAO.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.dao;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-
-public interface MembershipDAO extends DAO<Membership, Long> {
-
-    Membership find(Long key);
-
-    Membership find(User user, Group group);
-
-    List<Membership> findAll();
-
-    Membership save(Membership membership);
-
-    void delete(Long key);
-
-    Membership authFetch(Long key);
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainAttrDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainAttrDAO.java
index 1aa5d5c..e15b634 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainAttrDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainAttrDAO.java
@@ -20,11 +20,11 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 
-public interface PlainAttrDAO extends DAO<PlainAttr, Long> {
+public interface PlainAttrDAO extends DAO<PlainAttr<?>, Long> {
 
-    <T extends PlainAttr> T find(Long key, Class<T> reference);
+    <T extends PlainAttr<?>> T find(Long key, Class<T> reference);
 
-    <T extends PlainAttr> void delete(Long key, Class<T> reference);
+    <T extends PlainAttr<?>> void delete(Long key, Class<T> reference);
 
-    <T extends PlainAttr> void delete(T attr);
+    <T extends PlainAttr<?>> void delete(T attr);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
index 122faee..2dda81e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
@@ -19,19 +19,18 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 
 public interface PlainSchemaDAO extends DAO<PlainSchema, String> {
 
-    <T extends PlainSchema> T find(String key, Class<T> reference);
+    PlainSchema find(String name);
 
-    <T extends PlainSchema> List<T> findAll(Class<T> reference);
+    List<PlainSchema> findAll();
 
-    <T extends PlainAttr> List<T> findAttrs(PlainSchema schema, Class<T> reference);
+    <T extends PlainAttr<?>> List<T> findAttrs(PlainSchema schema, Class<T> reference);
 
-    <T extends PlainSchema> T save(T schema);
+    PlainSchema save(PlainSchema derSchema);
 
-    void delete(String name, AttributableUtils attributableUtil);
+    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
----------------------------------------------------------------------
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 dff687d..58281ff 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
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 
 public interface PolicyDAO extends DAO<Policy, Long> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
deleted file mode 100644
index aca7bf4..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.dao;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-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.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public interface SubjectDAO<P extends PlainAttr, D extends DerAttr, V extends VirAttr>
-        extends DAO<Subject<P, D, V>, Long> {
-
-    List<? extends Subject<P, D, V>> findByAttrValue(
-            String schemaName, PlainAttrValue attrValue, AttributableUtils attrUtils);
-
-    Subject<P, D, V> findByAttrUniqueValue(
-            String schemaName, PlainAttrValue attrUniqueValue, AttributableUtils attrUtils);
-
-    List<? extends Subject<P, D, V>> findByDerAttrValue(
-            String schemaName, String value, AttributableUtils attrUtils);
-
-    List<? extends Subject<P, D, V>> findByResource(
-            ExternalResource resource, AttributableUtils attrUtils);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
deleted file mode 100644
index a4cd7d4..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.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.api.dao;
-
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-
-public interface SubjectSearchDAO extends DAO<Subject<?, ?, ?>, Long> {
-
-    /**
-     * @param adminRealms realms for which the caller owns the proper entitlement(s)
-     * @param searchCondition the search condition
-     * @param type user or group
-     * @return size of search result
-     */
-    int count(Set<String> adminRealms, SearchCond searchCondition, SubjectType type);
-
-    /**
-     * @param adminRealms realms for which the caller owns the proper entitlement(s)
-     * @param searchCondition the search condition
-     * @param type user or group
-     * @param <T> user/group
-     * @return the list of users/groups matching the given search condition
-     */
-    <T extends Subject<?, ?, ?>> List<T> search(
-            Set<String> adminRealms, SearchCond searchCondition, SubjectType type);
-
-    /**
-     * @param adminRealms the set of admin groups owned by the caller
-     * @param searchCondition the search condition
-     * @param orderBy list of ordering clauses
-     * @param type user or group
-     * @param <T> user/group
-     * @return the list of users/groups matching the given search condition
-     */
-    <T extends Subject<?, ?, ?>> List<T> search(
-            Set<String> adminRealms, SearchCond searchCondition, List<OrderByClause> orderBy, SubjectType type);
-
-    /**
-     * @param adminRealms realms for which the caller owns the proper entitlement(s)
-     * @param searchCondition the search condition
-     * @param page position of the first result, start from 1
-     * @param itemsPerPage number of results per page
-     * @param orderBy list of ordering clauses
-     * @param type user or group
-     * @param <T> user/group
-     * @return the list of users/groups matching the given search condition (in the given page)
-     */
-    <T extends Subject<?, ?, ?>> List<T> search(
-            Set<String> adminRealms, SearchCond searchCondition, int page, int itemsPerPage,
-            List<OrderByClause> orderBy, SubjectType type);
-
-    /**
-     * Verify if user/group matches the given search condition.
-     *
-     * @param subject to be checked
-     * @param searchCondition to be verified
-     * @param type user or group
-     * @param <T> user/group
-     * @return true if user/group matches searchCondition
-     */
-    <T extends Subject<?, ?, ?>> boolean matches(T subject, SearchCond searchCondition, SubjectType type);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/TaskDAO.java
----------------------------------------------------------------------
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 0b82276..02b1032 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
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 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.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 
 public interface TaskDAO extends DAO<Task, Long> {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
----------------------------------------------------------------------
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 469a98f..a1e4d09 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
@@ -20,54 +20,22 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
-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.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.SecurityQuestion;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
-public interface UserDAO extends SubjectDAO<UPlainAttr, UDerAttr, UVirAttr> {
+public interface UserDAO extends AnyDAO<User> {
 
-    User find(Long key);
+    User authFind(String username);
 
     User find(String username);
 
-    User findByWorkflowId(String workflowId);
-
     User findByToken(String token);
 
     List<User> findBySecurityQuestion(SecurityQuestion securityQuestion);
 
-    List<User> findByDerAttrValue(String schemaName, String value);
-
-    List<User> findByAttrValue(String schemaName, UPlainAttrValue attrValue);
-
-    User findByAttrUniqueValue(String schemaName, UPlainAttrValue attrUniqueValue);
-
-    List<User> findByResource(ExternalResource resource);
-
-    List<User> findAll(Set<String> adminRealms, int page, int itemsPerPage);
-
-    List<User> findAll(Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
-
-    int count(Set<String> adminRealms);
-
-    User save(User user);
-
-    void delete(Long key);
-
-    void delete(User user);
-
-    User authFetch(Long key);
-
-    User authFetch(String username);
-
     List<Role> findDynRoleMemberships(User user);
 
     List<Group> findDynGroupMemberships(User user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
index 254372a..b62cb87 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirAttrDAO.java
@@ -21,15 +21,15 @@ package org.apache.syncope.core.persistence.api.dao;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 
-public interface VirAttrDAO extends DAO<VirAttr, Long> {
+public interface VirAttrDAO extends DAO<VirAttr<?>, Long> {
 
-    <T extends VirAttr> T find(Long key, Class<T> reference);
+    <T extends VirAttr<?>> T find(Long key, Class<T> reference);
 
-    <T extends VirAttr> List<T> findAll(Class<T> reference);
+    <T extends VirAttr<?>> List<T> findAll(Class<T> reference);
 
-    <T extends VirAttr> T save(T virtualAttribute);
+    <T extends VirAttr<?>> T save(T virtualAttribute);
 
-    <T extends VirAttr> void delete(Long key, Class<T> reference);
+    <T extends VirAttr<?>> void delete(Long key, Class<T> reference);
 
-    <T extends VirAttr> void delete(T virAttr);
+    <T extends VirAttr<?>> void delete(T virAttr);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
index 160f109..fc6c7fa 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,19 +19,18 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
 public interface VirSchemaDAO extends DAO<VirSchema, String> {
 
-    <T extends VirSchema> T find(String key, Class<T> reference);
+    VirSchema find(String name);
 
-    <T extends VirSchema> List<T> findAll(Class<T> reference);
+    List<VirSchema> findAll();
 
-    <T extends VirAttr> List<T> findAttrs(VirSchema virSchema, Class<T> reference);
+    <T extends VirAttr<?>> List<T> findAttrs(VirSchema virSchema, Class<T> reference);
 
-    <T extends VirSchema> T save(T virSchema);
+    VirSchema save(VirSchema derSchema);
 
-    void delete(String key, AttributableUtils attributableUtil);
+    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
new file mode 100644
index 0000000..8bc9669
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao.search;
+
+/**
+ * Search condition to be applied when comparing bean field values.
+ */
+public class AnyCond extends AttributeCond {
+
+    private static final long serialVersionUID = -1880319220462653955L;
+
+    public AnyCond() {
+        super();
+    }
+
+    public AnyCond(final Type conditionType) {
+        super(conditionType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/GroupCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/GroupCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/GroupCond.java
deleted file mode 100644
index 3dbb9b0..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/GroupCond.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.dao.search;
-
-public class GroupCond extends AbstractSearchCond {
-
-    private static final long serialVersionUID = -728155256293925989L;
-
-    private Long groupKey;
-
-    public Long getGroupKey() {
-        return groupKey;
-    }
-
-    public void setGroupKey(final Long groupKey) {
-        this.groupKey = groupKey;
-    }
-
-    @Override
-    public final boolean isValid() {
-        return groupKey != null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
new file mode 100644
index 0000000..8872107
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao.search;
+
+public class MembershipCond extends AbstractSearchCond {
+
+    private static final long serialVersionUID = -728155256293925989L;
+
+    private Long groupKey;
+
+    public Long getGroupKey() {
+        return groupKey;
+    }
+
+    public void setGroupKey(final Long groupKey) {
+        this.groupKey = groupKey;
+    }
+
+    @Override
+    public final boolean isValid() {
+        return groupKey != null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
new file mode 100644
index 0000000..ec26eb8
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.dao.search;
+
+public class RelationshipCond extends AbstractSearchCond {
+
+    private static final long serialVersionUID = 6865985945516722103L;
+
+    private Long anyObjectKey;
+
+    public Long getAnyObjectKey() {
+        return anyObjectKey;
+    }
+
+    public void setAnyObjectKey(final Long anyObjectKey) {
+        this.anyObjectKey = anyObjectKey;
+    }
+
+    @Override
+    public final boolean isValid() {
+        return anyObjectKey != null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
index ab5b527..d942591 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
@@ -35,11 +35,13 @@ public class SearchCond extends AbstractSearchCond {
 
     private Type type;
 
-    private SubjectCond subjectCond;
+    private AnyCond anyCond;
 
     private AttributeCond attributeCond;
 
-    private GroupCond groupCond;
+    private RelationshipCond relationshipCond;
+
+    private MembershipCond membershipCond;
 
     private RoleCond roleCond;
 
@@ -53,8 +55,8 @@ public class SearchCond extends AbstractSearchCond {
         SearchCond nodeCond = new SearchCond();
 
         nodeCond.type = Type.LEAF;
-        if (attributeCond instanceof SubjectCond) {
-            nodeCond.subjectCond = (SubjectCond) attributeCond;
+        if (attributeCond instanceof AnyCond) {
+            nodeCond.anyCond = (AnyCond) attributeCond;
         } else {
             nodeCond.attributeCond = attributeCond;
         }
@@ -62,11 +64,20 @@ public class SearchCond extends AbstractSearchCond {
         return nodeCond;
     }
 
-    public static SearchCond getLeafCond(final GroupCond groupCond) {
+    public static SearchCond getLeafCond(final RelationshipCond relationshipCond) {
+        SearchCond nodeCond = new SearchCond();
+
+        nodeCond.type = Type.LEAF;
+        nodeCond.relationshipCond = relationshipCond;
+
+        return nodeCond;
+    }
+
+    public static SearchCond getLeafCond(final MembershipCond membershipCond) {
         SearchCond nodeCond = new SearchCond();
 
         nodeCond.type = Type.LEAF;
-        nodeCond.groupCond = groupCond;
+        nodeCond.membershipCond = membershipCond;
 
         return nodeCond;
     }
@@ -95,8 +106,14 @@ public class SearchCond extends AbstractSearchCond {
         return nodeCond;
     }
 
-    public static SearchCond getNotLeafCond(final GroupCond groupCond) {
-        SearchCond nodeCond = getLeafCond(groupCond);
+    public static SearchCond getNotLeafCond(final RelationshipCond relationshipCond) {
+        SearchCond nodeCond = getLeafCond(relationshipCond);
+        nodeCond.type = Type.NOT_LEAF;
+        return nodeCond;
+    }
+
+    public static SearchCond getNotLeafCond(final MembershipCond membershipCond) {
+        SearchCond nodeCond = getLeafCond(membershipCond);
         nodeCond.type = Type.NOT_LEAF;
         return nodeCond;
     }
@@ -156,12 +173,12 @@ public class SearchCond extends AbstractSearchCond {
         }
     }
 
-    public SubjectCond getSubjectCond() {
-        return subjectCond;
+    public AnyCond getAnyCond() {
+        return anyCond;
     }
 
-    public void setSubjectCond(final SubjectCond subjectCond) {
-        this.subjectCond = subjectCond;
+    public void setAnyCond(final AnyCond anyCond) {
+        this.anyCond = anyCond;
     }
 
     public AttributeCond getAttributeCond() {
@@ -172,12 +189,20 @@ public class SearchCond extends AbstractSearchCond {
         this.attributeCond = attributeCond;
     }
 
-    public GroupCond getGroupCond() {
-        return groupCond;
+    public RelationshipCond getRelationshipCond() {
+        return relationshipCond;
+    }
+
+    public void setRelationshipCond(final RelationshipCond relationshipCond) {
+        this.relationshipCond = relationshipCond;
+    }
+
+    public MembershipCond getMembershipCond() {
+        return membershipCond;
     }
 
-    public void setGroupCond(final GroupCond groupCond) {
-        this.groupCond = groupCond;
+    public void setMembershipCond(final MembershipCond membershipCond) {
+        this.membershipCond = membershipCond;
     }
 
     public RoleCond getRoleCond() {
@@ -231,11 +256,12 @@ public class SearchCond extends AbstractSearchCond {
         switch (type) {
             case LEAF:
             case NOT_LEAF:
-                isValid = (subjectCond != null || attributeCond != null
-                        || groupCond != null || roleCond != null || resourceCond != null)
-                        && (subjectCond == null || subjectCond.isValid())
+                isValid = (anyCond != null || attributeCond != null
+                        || relationshipCond != null || membershipCond != null
+                        || roleCond != null || resourceCond != null)
+                        && (anyCond == null || anyCond.isValid())
                         && (attributeCond == null || attributeCond.isValid())
-                        && (groupCond == null || groupCond.isValid())
+                        && (membershipCond == null || membershipCond.isValid())
                         && (roleCond == null || roleCond.isValid())
                         && (resourceCond == null || resourceCond.isValid());
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SubjectCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SubjectCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SubjectCond.java
deleted file mode 100644
index 48e762f..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SubjectCond.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.dao.search;
-
-/**
- * Search condition to be applied when comparing bean field values.
- */
-public class SubjectCond extends AttributeCond {
-
-    private static final long serialVersionUID = -1880319220462653955L;
-
-    public SubjectCond() {
-        super();
-    }
-
-    public SubjectCond(final Type conditionType) {
-        super(conditionType);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
index e09aa2e..7a743c2 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AccountPolicy.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import java.util.Set;
 
 public interface AccountPolicy extends Policy {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
new file mode 100644
index 0000000..12bf9b6
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import java.util.List;
+
+public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>> extends AnnotatedEntity<Long> {
+
+    AnyType getType();
+
+    void setType(AnyType type);
+
+    Realm getRealm();
+
+    void setRealm(Realm realm);
+
+    String getStatus();
+
+    void setStatus(String status);
+
+    String getWorkflowId();
+
+    void setWorkflowId(String workflowId);
+
+    boolean add(P attr);
+
+    boolean remove(P attr);
+
+    P getPlainAttr(String plainSchemaName);
+
+    List<? extends P> getPlainAttrs();
+
+    boolean add(D derAttr);
+
+    boolean remove(D derAttr);
+
+    D getDerAttr(String derSchemaName);
+
+    List<? extends D> getDerAttrs();
+
+    boolean add(V virAttr);
+
+    boolean remove(V virAttr);
+
+    V getVirAttr(String virSchemaName);
+
+    List<? extends V> getVirAttrs();
+
+    boolean add(ExternalResource resource);
+
+    boolean remove(ExternalResource resource);
+
+    List<String> getResourceNames();
+
+    List<? extends ExternalResource> getResources();
+
+    boolean add(AnyTypeClass auxClass);
+
+    boolean remove(AnyTypeClass auxClass);
+
+    List<? extends AnyTypeClass> getAuxClasses();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyAbout.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyAbout.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyAbout.java
new file mode 100644
index 0000000..2f1684b
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyAbout.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+public interface AnyAbout extends Entity<Long> {
+
+    Notification getNotification();
+
+    void setNotification(Notification notification);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
+
+    String get();
+
+    void set(String filter);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
new file mode 100644
index 0000000..c23897c
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyType.java
@@ -0,0 +1,37 @@
+/*
+ * 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.AnyTypeKind;
+
+public interface AnyType extends Entity<String> {
+
+    void setKey(String key);
+
+    AnyTypeKind getKind();
+
+    void setKind(AnyTypeKind kind);
+
+    boolean add(AnyTypeClass anyTypeClass);
+
+    boolean remove(AnyTypeClass anyTypeClass);
+
+    List<? extends AnyTypeClass> getClasses();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
new file mode 100644
index 0000000..fdd00bb
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity;
+
+import java.util.List;
+
+public interface AnyTypeClass extends Entity<String> {
+
+    void setKey(String key);
+
+    boolean add(PlainSchema schema);
+
+    boolean remove(PlainSchema schema);
+
+    List<? extends PlainSchema> getPlainSchemas();
+
+    boolean add(DerSchema schema);
+
+    boolean remove(DerSchema schema);
+
+    List<? extends DerSchema> getDerSchemas();
+
+    boolean add(VirSchema schema);
+
+    boolean remove(VirSchema schema);
+
+    List<? extends VirSchema> getVirSchemas();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
new file mode 100644
index 0000000..836f0e3
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
@@ -0,0 +1,68 @@
+/*
+ * 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 org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import java.util.List;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+
+public interface AnyUtils {
+
+    AnyTypeKind getAnyTypeKind();
+
+    <T extends Any<?, ?, ?>> Class<T> anyClass();
+
+    <T extends PlainAttr<?>> Class<T> plainAttrClass();
+
+    <T extends PlainAttr<?>> T newPlainAttr();
+
+    <T extends PlainAttrValue> Class<T> plainAttrValueClass();
+
+    <T extends PlainAttrValue> T newPlainAttrValue();
+
+    <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass();
+
+    <T extends PlainAttrValue> T newPlainAttrUniqueValue();
+
+    <T extends DerAttr<?>> Class<T> derAttrClass();
+
+    <T extends DerAttr<?>> T newDerAttr();
+
+    <T extends VirAttr<?>> Class<T> virAttrClass();
+
+    <T extends VirAttr<?>> T newVirAttr();
+
+    MappingItem getConnObjectKeyItem(Provision provision);
+
+    String getConnObjectLink(Provision provision);
+
+    List<MappingItem> getMappingItems(Provision provision, MappingPurpose purpose);
+
+    IntMappingType plainIntMappingType();
+
+    IntMappingType derIntMappingType();
+
+    IntMappingType virIntMappingType();
+
+    <T extends AnyTO> T newAnyTO();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
new file mode 100644
index 0000000..2e2a49e
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtilsFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity;
+
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public interface AnyUtilsFactory {
+
+    AnyUtils getInstance(AnyTypeKind anyTypeKind);
+
+    AnyUtils getInstance(String anyTypeKind);
+
+    AnyUtils getInstance(Any<?, ?, ?> any);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
index 144962e..2be01e9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attr.java
@@ -18,11 +18,11 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
-public interface Attr<S extends Schema> extends Entity<Long> {
+public interface Attr<S extends Schema, O extends Any<?, ?, ?>> extends Entity<Long> {
 
-    Attributable<?, ?, ?> getOwner();
+    O getOwner();
 
-    void setOwner(Attributable<?, ?, ?> owner);
+    void setOwner(O owner);
 
     S getSchema();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttrTemplate.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttrTemplate.java
deleted file mode 100644
index 6aaf916..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttrTemplate.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity;
-
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-
-public interface AttrTemplate<S extends Schema> extends Entity<Long> {
-
-    Group getOwner();
-
-    void setOwner(Group group);
-
-    S getSchema();
-
-    void setSchema(S schema);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attributable.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attributable.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attributable.java
deleted file mode 100644
index e89181c..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Attributable.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity;
-
-import java.util.List;
-
-public interface Attributable<P extends PlainAttr, D extends DerAttr, V extends VirAttr> extends AnnotatedEntity<Long> {
-
-    boolean addPlainAttr(P attr);
-
-    boolean addDerAttr(D derAttr);
-
-    boolean addVirAttr(V virAttr);
-
-    boolean removePlainAttr(P attr);
-
-    boolean removeDerAttr(D derAttr);
-
-    boolean removeVirAttr(V virAttr);
-
-    P getPlainAttr(String plainSchemaName);
-
-    List<? extends P> getPlainAttrs();
-
-    D getDerAttr(String derSchemaName);
-
-    List<? extends D> getDerAttrs();
-
-    V getVirAttr(String virSchemaName);
-
-    List<? extends V> getVirAttrs();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
deleted file mode 100644
index 9539604..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
+++ /dev/null
@@ -1,89 +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.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-
-public interface AttributableUtils {
-
-    AttributableType getType();
-
-    <T extends Attributable<?, ?, ?>> Class<T> attributableClass();
-
-    <T extends PlainSchema> Class<T> plainSchemaClass();
-
-    <T extends PlainSchema> T newPlainSchema();
-
-    <T extends PlainAttr> Class<T> plainAttrClass();
-
-    <T extends PlainAttr> T newPlainAttr();
-
-    <T extends PlainAttrValue> Class<T> plainAttrValueClass();
-
-    <T extends PlainAttrValue> T newPlainAttrValue();
-
-    <T extends AttrTemplate<PlainSchema>> Class<T> plainAttrTemplateClass();
-
-    <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass();
-
-    <T extends PlainAttrValue> T newPlainAttrUniqueValue();
-
-    <T extends DerSchema> Class<T> derSchemaClass();
-
-    <T extends DerSchema> T newDerSchema();
-
-    <T extends DerAttr> Class<T> derAttrClass();
-
-    <T extends DerAttr> T newDerAttr();
-
-    <T extends AttrTemplate<DerSchema>> Class<T> derAttrTemplateClass();
-
-    <T extends VirSchema> Class<T> virSchemaClass();
-
-    <T extends VirSchema> T newVirSchema();
-
-    <T extends VirAttr> Class<T> virAttrClass();
-
-    <T extends VirAttr> T newVirAttr();
-
-    <T extends AttrTemplate<VirSchema>> Class<T> virAttrTemplateClass();
-
-    <T extends MappingItem> T getAccountIdItem(ExternalResource resource);
-
-    String getAccountLink(ExternalResource resource);
-
-    <T extends MappingItem> List<T> getMappingItems(ExternalResource resource, MappingPurpose purpose);
-
-    IntMappingType plainIntMappingType();
-
-    IntMappingType derIntMappingType();
-
-    IntMappingType virIntMappingType();
-
-    <T extends MappingItem> Class<T> mappingItemClass();
-
-    <T extends AbstractAttributableTO> T newAttributableTO();
-
-    <T extends AbstractSubjectTO> T newSubjectTO();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtilsFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtilsFactory.java
deleted file mode 100644
index 4b5e363..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtilsFactory.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.core.persistence.api.entity;
-
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-
-public interface AttributableUtilsFactory {
-
-    AttributableUtils getInstance(AttributableType type);
-
-    AttributableUtils getInstance(String attributableType);
-
-    AttributableUtils getInstance(ObjectClass objectClass);
-
-    AttributableUtils getInstance(Attributable<?, ?, ?> attributable);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ConnInstance.java
----------------------------------------------------------------------
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 88e8b00..eb665ea 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
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import java.util.List;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
index 2fbecc3..ba0a62f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynMembership.java
@@ -19,17 +19,16 @@
 package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 
-public interface DynMembership extends Entity<Long> {
+public interface DynMembership<A extends Any<?, ?, ?>> extends Entity<Long> {
 
     String getFIQLCond();
 
     void setFIQLCond(String fiql);
 
-    boolean addUser(User user);
+    boolean add(A any);
 
-    boolean removeUser(User user);
+    boolean remove(A any);
 
-    List<? extends User> getUsers();
+    List<? extends A> getMembers();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRoleMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRoleMembership.java
deleted file mode 100644
index 5321434..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/DynRoleMembership.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;
-
-public interface DynRoleMembership extends DynMembership {
-
-    Role getRole();
-
-    void setRole(Role role);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
deleted file mode 100644
index c221f41..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/ExternalResource.java
+++ /dev/null
@@ -1,111 +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 org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PropagationMode;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-public interface ExternalResource extends AnnotatedEntity<String> {
-
-    AccountPolicy getAccountPolicy();
-
-    PasswordPolicy getPasswordPolicy();
-
-    SyncPolicy getSyncPolicy();
-
-    Set<ConnConfProperty> getConnInstanceConfiguration();
-
-    ConnInstance getConnector();
-
-    TraceLevel getCreateTraceLevel();
-
-    TraceLevel getUpdateTraceLevel();
-
-    TraceLevel getDeleteTraceLevel();
-
-    TraceLevel getSyncTraceLevel();
-
-    List<String> getPropagationActionsClassNames();
-
-    PropagationMode getPropagationMode();
-
-    Integer getPropagationPriority();
-
-    UMapping getUmapping();
-
-    GMapping getGmapping();
-
-    SyncToken getUsyncToken();
-
-    String getSerializedUSyncToken();
-
-    SyncToken getRsyncToken();
-
-    String getSerializedRSyncToken();
-
-    boolean isEnforceMandatoryCondition();
-
-    boolean isPropagationPrimary();
-
-    boolean isRandomPwdIfNotProvided();
-
-    void setKey(String name);
-
-    void setAccountPolicy(AccountPolicy accountPolicy);
-
-    void setPasswordPolicy(PasswordPolicy passwordPolicy);
-
-    void setSyncPolicy(SyncPolicy syncPolicy);
-
-    void setConnInstanceConfiguration(Set<ConnConfProperty> properties);
-
-    void setConnector(ConnInstance connector);
-
-    void setCreateTraceLevel(TraceLevel createTraceLevel);
-
-    void setUpdateTraceLevel(TraceLevel updateTraceLevel);
-
-    void setDeleteTraceLevel(TraceLevel deleteTraceLevel);
-
-    void setSyncTraceLevel(TraceLevel syncTraceLevel);
-
-    void setPropagationMode(PropagationMode propagationMode);
-
-    void setPropagationPriority(Integer priority);
-
-    void setUmapping(UMapping umapping);
-
-    void setGmapping(GMapping gmapping);
-
-    void setEnforceMandatoryCondition(boolean enforce);
-
-    void setPropagationPrimary(boolean condition);
-
-    void setRandomPwdIfNotProvided(boolean condition);
-
-    void setUsyncToken(SyncToken syncToken);
-
-    void setRsyncToken(SyncToken syncToken);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Mapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Mapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Mapping.java
deleted file mode 100644
index fb491fa..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/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;
-
-import java.util.List;
-
-public interface Mapping<T extends MappingItem> extends Entity<Long> {
-
-    T getAccountIdItem();
-
-    String getAccountLink();
-
-    List<? extends T> getItems();
-
-    ExternalResource getResource();
-
-    boolean addItem(T item);
-
-    boolean removeItem(T item);
-
-    void setAccountIdItem(T item);
-
-    void setAccountLink(String accountLink);
-
-    void setResource(ExternalResource resource);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MappingItem.java
deleted file mode 100644
index ec6919e..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MappingItem.java
+++ /dev/null
@@ -1,57 +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 org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-
-public interface MappingItem extends Entity<Long> {
-
-    String getExtAttrName();
-
-    String getIntAttrName();
-
-    IntMappingType getIntMappingType();
-
-    String getMandatoryCondition();
-
-    Mapping<?> getMapping();
-
-    MappingPurpose getPurpose();
-
-    boolean isAccountid();
-
-    boolean isPassword();
-
-    void setAccountid(boolean accountid);
-
-    void setExtAttrName(String extAttrName);
-
-    void setIntAttrName(String intAttrName);
-
-    void setIntMappingType(IntMappingType intMappingType);
-
-    void setMandatoryCondition(String condition);
-
-    void setMapping(Mapping<?> mapping);
-
-    void setPassword(boolean password);
-
-    void setPurpose(MappingPurpose purpose);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
new file mode 100644
index 0000000..8c040ab
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Membership.java
@@ -0,0 +1,25 @@
+/*
+ * 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 org.apache.syncope.core.persistence.api.entity.group.Group;
+
+public interface Membership<L extends Any<?, ?, ?>> extends Relationship<L, Group> {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
index e505f24..dbf8552 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Notification.java
@@ -26,49 +26,50 @@ public interface Notification extends Entity<Long> {
 
     List<String> getEvents();
 
-    String getRecipientAttrName();
-
-    IntMappingType getRecipientAttrType();
-
-    String getRecipients();
-
-    String getGroupAbout();
+    boolean isSelfAsRecipient();
 
-    String getSender();
+    void setSelfAsRecipient(boolean selfAsRecipient);
 
     List<String> getStaticRecipients();
 
-    String getSubject();
-
-    String getTemplate();
+    String getRecipientAttrName();
 
-    TraceLevel getTraceLevel();
+    void setRecipientAttrName(String recipientAttrName);
 
-    String getUserAbout();
+    IntMappingType getRecipientAttrType();
 
-    boolean isActive();
+    void setRecipientAttrType(IntMappingType recipientAttrType);
 
-    boolean isSelfAsRecipient();
+    String getRecipients();
 
-    void setActive(boolean active);
+    void setRecipients(String recipients);
 
-    void setRecipientAttrName(String recipientAttrName);
+    boolean add(AnyAbout about);
 
-    void setRecipientAttrType(IntMappingType recipientAttrType);
+    boolean remove(AnyAbout about);
 
-    void setRecipients(String recipients);
+    AnyAbout getAbout(AnyType anyType);
 
-    void setGroupAbout(String groupAbout);
+    List<? extends AnyAbout> getAbouts();
 
-    void setSelfAsRecipient(boolean selfAsRecipient);
+    String getSender();
 
     void setSender(String sender);
 
+    String getSubject();
+
     void setSubject(String subject);
 
+    String getTemplate();
+
     void setTemplate(String template);
 
+    TraceLevel getTraceLevel();
+
     void setTraceLevel(TraceLevel traceLevel);
 
-    void setUserAbout(String userAbout);
+    boolean isActive();
+
+    void setActive(boolean active);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
index 8474778..b149851 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
@@ -20,17 +20,20 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 
-public interface PlainAttr extends Attr<PlainSchema> {
+public interface PlainAttr<O extends Any<?, ?, ?>> extends Attr<PlainSchema, O> {
 
-    void addValue(String value, AttributableUtils attributableUtil);
+    void add(String value, AnyUtils anyUtils);
 
-    boolean removeValue(PlainAttrValue attrValue);
+    void add(String value, PlainAttrValue attrValue);
+
+    boolean remove(PlainAttrValue attrValue);
 
     PlainAttrUniqueValue getUniqueValue();
 
+    void setUniqueValue(PlainAttrUniqueValue uniqueValue);
+
     List<? extends PlainAttrValue> getValues();
 
     List<String> getValuesAsStrings();
 
-    void setUniqueValue(PlainAttrUniqueValue uniqueValue);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttrValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttrValue.java
index 7735d4c..e1f43b6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttrValue.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttrValue.java
@@ -23,7 +23,7 @@ import org.apache.syncope.common.lib.types.AttrSchemaType;
 
 public interface PlainAttrValue extends Entity<Long> {
 
-    PlainAttr getAttr();
+    PlainAttr<?> getAttr();
 
     byte[] getBinaryValue();
 
@@ -45,7 +45,7 @@ public interface PlainAttrValue extends Entity<Long> {
 
     void parseValue(PlainSchema schema, String value);
 
-    void setAttr(PlainAttr attr);
+    void setAttr(PlainAttr<?> attr);
 
     void setBinaryValue(byte[] binaryValue);
 

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
index 5a9fe86..432efb1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 import java.util.List;
 import java.util.Set;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
deleted file mode 100644
index 11f0c81..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
+++ /dev/null
@@ -1,36 +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.Set;
-
-public interface Subject<N extends PlainAttr, D extends DerAttr, V extends VirAttr> extends Attributable<N, D, V> {
-
-    Realm getRealm();
-
-    void setRealm(Realm realm);
-
-    boolean addResource(ExternalResource resource);
-
-    boolean removeResource(ExternalResource resource);
-
-    Set<String> getResourceNames();
-
-    Set<? extends ExternalResource> getResources();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
index 9df47cd..7761d93 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirAttr.java
@@ -20,11 +20,11 @@ package org.apache.syncope.core.persistence.api.entity;
 
 import java.util.List;
 
-public interface VirAttr extends Attr<VirSchema> {
+public interface VirAttr<O extends Any<?, ?, ?>> extends Attr<VirSchema, O> {
 
     List<String> getValues();
 
-    boolean addValue(String value);
+    boolean add(String value);
 
-    boolean removeValue(String value);
+    boolean remove(String value);
 }

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


[09/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
new file mode 100644
index 0000000..d6ff876
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyTransformer.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+
+/**
+ * Provides logic for transforming any object, received as input by RESTful methods, before any internal
+ * processing logic takes place.
+ */
+public interface AnyTransformer {
+
+    <T extends AnyTO> T transform(T input);
+
+    <T extends AnyMod> T transform(T input);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AttributableTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AttributableTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AttributableTransformer.java
deleted file mode 100644
index 5e8b9e7..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AttributableTransformer.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.core.provisioning.api;
-
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-
-/**
- * Provides logic for transforming user or group, received as input by RESTful methods, before any internal
- * processing logic takes place.
- */
-public interface AttributableTransformer {
-
-    <T extends AbstractAttributableTO> T transform(T input);
-
-    <T extends AbstractAttributableMod> T transform(T input);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
index 61ff143..53cae3e 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
index e4c6392..6d2d0c8 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java
@@ -22,7 +22,7 @@ import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 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.resource.ExternalResource;
 
 /**
  * Entry point for creating and destroying connectors for external resources.

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorRegistry.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorRegistry.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorRegistry.java
index ce5f837..1bcbcbc 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorRegistry.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorRegistry.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.api;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 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.resource.ExternalResource;
 
 /**
  * Manage Spring beans lifecycle for connectors.

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
index 6989f8c..0913405 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
@@ -33,6 +33,6 @@ public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, G
     Pair<Long, List<PropagationStatus>> create(
             GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources);
 
-    Pair<Long, List<PropagationStatus>> update(GroupMod subjectMod, Set<String> excludedResources);
+    Pair<Long, List<PropagationStatus>> update(GroupMod groupMod, Set<String> excludedResources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java
index 95450e2..28b2663 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisioningManager.java
@@ -21,22 +21,22 @@ package org.apache.syncope.core.provisioning.api;
 import java.util.Collection;
 import java.util.List;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 
-public interface ProvisioningManager<T extends AbstractAttributableTO, M extends AbstractAttributableMod> {
+public interface ProvisioningManager<T extends AnyTO, M extends AnyMod> {
 
-    Pair<Long, List<PropagationStatus>> create(T subject);
+    Pair<Long, List<PropagationStatus>> create(T anyTO);
 
-    Pair<Long, List<PropagationStatus>> update(M subjectMod);
+    Pair<Long, List<PropagationStatus>> update(M anyMod);
 
-    List<PropagationStatus> delete(Long subjectId);
+    List<PropagationStatus> delete(Long anyKey);
 
-    Long unlink(M subjectMod);
+    Long unlink(M anyMod);
 
-    Long link(M subjectMod);
+    Long link(M anyMod);
 
-    List<PropagationStatus> deprovision(Long user, Collection<String> resources);
+    List<PropagationStatus> deprovision(Long anyKey, Collection<String> resources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 19a1aed..ad7a01e 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -43,12 +43,10 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
     Pair<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword,
             boolean disablePwdPolicyCheck, Boolean enabled, Set<String> excludedResources);
 
-    Pair<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships);
-
     Pair<Long, List<PropagationStatus>> update(UserMod userMod, Long key,
             ProvisioningResult result, Boolean enabled, Set<String> excludedResources);
 
-    List<PropagationStatus> delete(Long subjectKey, Set<String> excludedResources);
+    List<PropagationStatus> delete(Long key, Set<String> excludedResources);
 
     void requestPasswordReset(Long key);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCache.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCache.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCache.java
index 45256e5..7ab5d9b 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCache.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCache.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.api.cache;
 
-import org.apache.syncope.common.lib.types.AttributableType;
-
 /**
  * Virtual Attribute Value cache.
  */
@@ -28,21 +26,21 @@ public interface VirAttrCache {
     /**
      * Force entry expiring.
      *
-     * @param type user or group
-     * @param id user or group id
+     * @param type any object
+     * @param key any object key
      * @param schemaName virtual attribute schema name
      */
-    void expire(AttributableType type, Long id, String schemaName);
+    void expire(String type, Long key, String schemaName);
 
     /**
      * Retrieve cached value. Return null in case of virtual attribute not cached.
      *
-     * @param type user or group
-     * @param id user or group id
+     * @param type any object
+     * @param key any object key
      * @param schemaName virtual attribute schema name.
      * @return cached values or null if virtual attribute is not cached.
      */
-    VirAttrCacheValue get(AttributableType type, Long id, String schemaName);
+    VirAttrCacheValue get(String type, Long key, String schemaName);
 
     /**
      * Cache entry is valid if and only if value exist and it is not expired.
@@ -55,11 +53,11 @@ public interface VirAttrCache {
     /**
      * Cache virtual attribute values.
      *
-     * @param type user or group
-     * @param id user or group id
+     * @param type any object
+     * @param key any object key
      * @param schemaName virtual attribute name
      * @param value virtual attribute values
      */
-    void put(AttributableType type, Long id, String schemaName, VirAttrCacheValue value);
+    void put(String type, Long key, String schemaName, VirAttrCacheValue value);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCacheKey.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCacheKey.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCacheKey.java
index a33a740..da74000 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCacheKey.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/cache/VirAttrCacheKey.java
@@ -22,7 +22,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.types.AttributableType;
 
 /**
  * Cache entry key.
@@ -30,12 +29,12 @@ import org.apache.syncope.common.lib.types.AttributableType;
 public class VirAttrCacheKey {
 
     /**
-     * Subject type.
+     * Any type name.
      */
-    private final AttributableType type;
+    private final String type;
 
     /**
-     * Subject key.
+     * Any object key.
      */
     private final transient Long key;
 
@@ -44,13 +43,13 @@ public class VirAttrCacheKey {
      */
     private final transient String virSchema;
 
-    public VirAttrCacheKey(final AttributableType type, final Long key, final String virSchema) {
+    public VirAttrCacheKey(final String type, final Long key, final String virSchema) {
         this.type = type;
         this.key = key;
         this.virSchema = virSchema;
     }
 
-    public AttributableType getType() {
+    public String getKind() {
         return type;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyObjectDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyObjectDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyObjectDataBinder.java
new file mode 100644
index 0000000..b503365
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyObjectDataBinder.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api.data;
+
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+
+public interface AnyObjectDataBinder {
+
+    AnyObjectTO getAnyObjectTO(Long key);
+
+    AnyObjectTO getAnyObjectTO(AnyObject anyObject);
+
+    void create(AnyObject anyObject, AnyObjectTO anyObjectTO);
+
+    PropagationByResource update(AnyObject toBeUpdated, AnyObjectMod anyObjectMod);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ResourceDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ResourceDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ResourceDataBinder.java
index babfb5e..2d96d71 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ResourceDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ResourceDataBinder.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.provisioning.api.data;
 
 import org.apache.syncope.common.lib.to.ResourceTO;
 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.resource.ExternalResource;
 
 public interface ResourceDataBinder {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
index cb1525e..dcb8f9f 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.api.data;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -36,11 +35,11 @@ public interface SchemaDataBinder {
 
     <T extends DerSchema> DerSchemaTO getDerSchemaTO(T derSchema);
 
-    <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(T schema, AttributableUtils attributableUtil);
+    <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(T schema);
 
     <T extends VirSchema> VirSchemaTO getVirSchemaTO(T virSchema);
 
-    <T extends PlainSchema> void update(PlainSchemaTO schemaTO, T schema, AttributableUtils attributableUtil);
+    <T extends PlainSchema> void update(PlainSchemaTO schemaTO, T schema);
 
     <T extends DerSchema> T update(DerSchemaTO derSchemaTO, T derSchema);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
index db76ca1..36821c3 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
@@ -23,14 +23,12 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 
 public interface PropagationManager {
@@ -92,7 +90,7 @@ public interface PropagationManager {
     List<PropagationTask> getGroupDeleteTasks(Long groupKey, String noPropResourceName);
 
     /**
-     * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
+     * Perform delete on each resource associated to the group. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
@@ -103,7 +101,7 @@ public interface PropagationManager {
     List<PropagationTask> getGroupDeleteTasks(Long groupKey, Collection<String> noPropResourceNames);
 
     /**
-     * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
+     * Perform delete on each resource associated to the group. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
@@ -115,6 +113,13 @@ public interface PropagationManager {
     List<PropagationTask> getGroupDeleteTasks(
             Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
 
+    List<PropagationTask> getAnyObjectCreateTasks(Long anyObjectKey, Collection<AttrTO> vAttrs,
+            PropagationByResource propByRes, List<String> noPropResourceNames);
+
+    List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, String noPropResourceName);
+
+    List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, Collection<String> noPropResourceNames);
+
     /**
      * Create the user on every associated resource.
      *
@@ -124,12 +129,11 @@ public interface PropagationManager {
      * @param password to be set
      * @param vAttrs virtual attributes to be set
      * @param noPropResourceNames external resources not to be considered for propagation
-     * @param membershipTOs user memberships
      * @return list of propagation tasks
      */
     List<PropagationTask> getUserCreateTasks(Long key, Boolean enable,
             PropagationByResource propByRes, String password, Collection<AttrTO> vAttrs,
-            Collection<MembershipTO> membershipTOs, Collection<String> noPropResourceNames);
+            Collection<String> noPropResourceNames);
 
     /**
      * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
@@ -154,10 +158,9 @@ public interface PropagationManager {
 
     List<PropagationTask> getUserUpdateTasks(WorkflowResult<Pair<UserMod, Boolean>> wfResult);
 
-    List<PropagationTask> getUpdateTasks(Subject<?, ?, ?> subject, String password, boolean changePwd,
+    List<PropagationTask> getUpdateTasks(Any<?, ?, ?> any, String password, boolean changePwd,
             Boolean enable, Set<String> vAttrsToBeRemoved, Set<AttrMod> vAttrsToBeUpdated,
-            PropagationByResource propByRes, Collection<String> noPropResourceNames,
-            Set<MembershipMod> membershipsToAdd);
+            PropagationByResource propByRes, Collection<String> noPropResourceNames);
 
     /**
      * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
index 5bebeb9..8bc9da5 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.provisioning.api.sync;
 
 /**
- * Raised by {@link SyncActions} or {@link PushActions} methods when the given subject is to be ignored for
+ * Raised by {@link SyncActions} or {@link PushActions} methods when the given any object is to be ignored for
  * synchronization / push.
  */
 public class IgnoreProvisionException extends RuntimeException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningResult.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningResult.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningResult.java
index 3253bc3..23af92d 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningResult.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningResult.java
@@ -23,7 +23,6 @@ import java.util.Collection;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TraceLevel;
 
@@ -41,7 +40,7 @@ public class ProvisioningResult {
 
     private Status status;
 
-    private AttributableType subjectType;
+    private String anyType;
 
     private ResourceOperation operation;
 
@@ -81,12 +80,12 @@ public class ProvisioningResult {
         this.status = status;
     }
 
-    public AttributableType getSubjectType() {
-        return subjectType;
+    public String getAnyType() {
+        return anyType;
     }
 
-    public void setSubjectType(final AttributableType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyType(final String anyType) {
+        this.anyType = anyType;
     }
 
     public ResourceOperation getOperation() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
index f66acde..e5ce13b 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
@@ -18,137 +18,137 @@
  */
 package org.apache.syncope.core.provisioning.api.sync;
 
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.quartz.JobExecutionException;
 
 /**
  * Interface for actions to be performed during PushJob execution.
  * <br/>
- * All methods can throw {@link IgnoreProvisionException} to make the current subject ignored by the push process.
+ * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
  */
 public interface PushActions extends ProvisioningActions {
 
     /**
-     * Action to be executed before to assign (link & provision) a synchronized user / group to the resource.
+     * Action to be executed before to assign (link & provision) a synchronized any object to the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeAssign(
+    <T extends Any<?, ?, ?>> T beforeAssign(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to provision a synchronized user / group to the resource.
+     * Action to be executed before to provision a synchronized any object to the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeProvision(
+    <T extends Any<?, ?, ?>> T beforeProvision(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to update a synchronized user / group on the resource.
+     * Action to be executed before to update a synchronized any object on the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be updated.
-     * @return subject.
+     * @param any any object to be updated.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeUpdate(
+    <T extends Any<?, ?, ?>> T beforeUpdate(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to link a synchronized user / group to the resource.
+     * Action to be executed before to link a synchronized any object to the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeLink(
+    <T extends Any<?, ?, ?>> T beforeLink(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unlink a synchronized user / group from the resource.
+     * Action to be executed before to unlink a synchronized any object from the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeUnlink(
+    <T extends Any<?, ?, ?>> T beforeUnlink(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user / group from the resource.
+     * Action to be executed before to unassign a synchronized any object from the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeUnassign(
+    <T extends Any<?, ?, ?>> T beforeUnassign(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user / group from the resource.
+     * Action to be executed before to unassign a synchronized any object from the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeDeprovision(
+    <T extends Any<?, ?, ?>> T beforeDeprovision(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed before delete a synchronized user / group locally and from the resource.
+     * Action to be executed before delete a synchronized any object locally and from the resource.
      *
      * @param profile profile of the push being executed.
-     * @param subject user / group to be created.
-     * @return subject.
+     * @param any any object to be created.
+     * @return any.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> T beforeDelete(
+    <T extends Any<?, ?, ?>> T beforeDelete(
             ProvisioningProfile<?, ?> profile,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
-     * Action to be executed after user / group push goes on error.
+     * Action to be executed after any object push goes on error.
      *
      * @param profile profile of the push being executed.
-     * @param subject synchronized user / group.
+     * @param any synchronized any object.
      * @param result operation result.
      * @param error error being reported
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> void onError(
+    <T extends Any<?, ?, ?>> void onError(
             ProvisioningProfile<?, ?> profile,
-            T subject,
+            T any,
             ProvisioningResult result,
             Exception error) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user / group push.
+     * Action to be executed after each local any object push.
      *
      * @param profile profile of the push being executed.
-     * @param subject synchronized user / group.
+     * @param any synchronized any object.
      * @param result operation result.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends Subject<?, ?, ?>> void after(
+    <T extends Any<?, ?, ?>> void after(
             ProvisioningProfile<?, ?> profile,
-            T subject,
+            T any,
             ProvisioningResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
index ba577de..82dd9d4 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
@@ -18,15 +18,15 @@
  */
 package org.apache.syncope.core.provisioning.api.sync;
 
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.quartz.JobExecutionException;
 
 /**
  * Interface for actions to be performed during SyncJob execution.
  * <br/>
- * All methods can throw {@link IgnoreProvisionException} to make the current subject ignored by the synchronization
+ * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the synchronization
  * process.
  */
 public interface SyncActions extends ProvisioningActions {
@@ -38,14 +38,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+    <T extends AnyTO> SyncDelta beforeProvision(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before creating (and linking to the resource) a synchronized user / group locally.
@@ -54,14 +54,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeAssign(
+    <T extends AnyTO> SyncDelta beforeAssign(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / group and de-provisioning.
@@ -70,14 +70,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeUnassign(
+    <T extends AnyTO> SyncDelta beforeUnassign(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before de-provisioning action only.
@@ -86,14 +86,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeDeprovision(
+    <T extends AnyTO> SyncDelta beforeDeprovision(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before unlinking resource from the synchronized user / group.
@@ -102,14 +102,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeUnlink(
+    <T extends AnyTO> SyncDelta beforeUnlink(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before linking resource to the synchronized user / group.
@@ -118,14 +118,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / group to be created
+     * @param any any object
      * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeLink(
+    <T extends AnyTO> SyncDelta beforeLink(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed before to update a synchronized user / group locally.
@@ -134,16 +134,16 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject local user / group information
-     * @param subjectMod modification
+     * @param any any object
+     * @param anyMod modification
      * @return synchronization information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure.
      */
-    <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject,
-            K subjectMod)
+            T any,
+            K anyMod)
             throws JobExecutionException;
 
     /**
@@ -151,14 +151,14 @@ public interface SyncActions extends ProvisioningActions {
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject local user / group to be deleted
+     * @param any any object to be deleted
      * @return synchronization information used for logging and to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> SyncDelta beforeDelete(
+    <T extends AnyTO> SyncDelta beforeDelete(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject) throws JobExecutionException;
+            T any) throws JobExecutionException;
 
     /**
      * Action to be executed when user / group synchronization goes on error.
@@ -182,13 +182,13 @@ public interface SyncActions extends ProvisioningActions {
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information (may be modified by
      * 'beforeProvision/beforeUpdate/beforeDelete')
-     * @param subject synchronized local user / group
+     * @param any any object
      * @param result global synchronization results at the current synchronization step
      * @throws JobExecutionException in case of generic failure
      */
-    <T extends AbstractSubjectTO> void after(
+    <T extends AnyTO> void after(
             ProvisioningProfile<?, ?> profile,
             SyncDelta delta,
-            T subject,
+            T any,
             ProvisioningResult result) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
index 6ac156f..e77af9a 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
@@ -22,5 +22,5 @@ import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 
 public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
 
-    boolean handle(long subjectId);
+    boolean handle(long anyKey);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index 3c76b82..cc49d62 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -33,12 +33,12 @@ import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.identityconnectors.common.security.GuardedByteArray;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.APIConfiguration;
@@ -536,7 +536,7 @@ public class ConnectorFacadeProxy implements Connector {
         // -------------------------------------
         final OperationOptionsBuilder oob = new OperationOptionsBuilder();
 
-        final Set<String> attrsToGet = new HashSet<String>();
+        final Set<String> attrsToGet = new HashSet<>();
         attrsToGet.add(Name.NAME);
         attrsToGet.add(Uid.NAME);
         attrsToGet.add(OperationalAttributes.ENABLE_NAME);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index e9041fe..7d0cf2f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -27,12 +27,12 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 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.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.api.ConnectorFacadeFactory;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
new file mode 100644
index 0000000..f7f6bfb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyTransformer.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
+
+/**
+ * Default empty implementation returning received input as result.
+ */
+public class DefaultAnyTransformer implements AnyTransformer {
+
+    @Override
+    public <T extends AnyTO> T transform(final T input) {
+        return input;
+    }
+
+    @Override
+    public <T extends AnyMod> T transform(final T input) {
+        return input;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAttributableTransformer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAttributableTransformer.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAttributableTransformer.java
deleted file mode 100644
index d1a14f0..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAttributableTransformer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java;
-
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
-
-/**
- * Default empty implementation returning received input as result.
- */
-public class DefaultAttributableTransformer implements AttributableTransformer {
-
-    @Override
-    public <T extends AbstractAttributableTO> T transform(final T input) {
-        return input;
-    }
-
-    @Override
-    public <T extends AbstractAttributableMod> T transform(final T input) {
-        return input;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index bf16b8d..f0344b4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -137,12 +137,12 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     public List<PropagationStatus> delete(final Long subjectKey) {
         final List<PropagationTask> tasks = new ArrayList<>();
 
-        Group group = groupDAO.authFetch(subjectKey);
+        Group group = groupDAO.authFind(subjectKey);
         if (group != null) {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
             for (Map.Entry<Long, PropagationByResource> entry
-                    : groupDAO.findUsersWithIndirectResources(group.getKey()).entrySet()) {
+                    : groupDAO.findAnyObjectsWithTransitiveResources(group.getKey()).entrySet()) {
 
                 WorkflowResult<Long> wfResult =
                         new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
@@ -179,7 +179,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
     @Override
     public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(group.getResourceNames(), resources);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 2f959b5..5826786 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -26,7 +26,6 @@ import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -94,7 +93,6 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 created.getPropByRes(),
                 userTO.getPassword(),
                 userTO.getVirAttrs(),
-                userTO.getMemberships(),
                 excludedResources);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
@@ -110,35 +108,16 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
     @Override
     public Pair<Long, List<PropagationStatus>> update(final UserMod userMod) {
-        return update(userMod, false);
-    }
-
-    @Override
-    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final boolean removeMemberships) {
         WorkflowResult<Pair<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated);
         if (tasks.isEmpty()) {
             // SYNCOPE-459: take care of user virtual attributes ...
-            final PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
                     updated.getResult().getKey().getKey(),
                     userMod.getVirAttrsToRemove(),
                     userMod.getVirAttrsToUpdate());
-            // SYNCOPE-501: update only virtual attributes (if any of them changed), password propagation is
-            // not required, take care also of membership virtual attributes
-            boolean addOrUpdateMemberships = false;
-            for (MembershipMod membershipMod : userMod.getMembershipsToAdd()) {
-                if (!virtAttrHandler.fillMembershipVirtual(
-                        updated.getResult().getKey().getKey(),
-                        membershipMod.getGroup(),
-                        null,
-                        membershipMod.getVirAttrsToRemove(),
-                        membershipMod.getVirAttrsToUpdate(),
-                        false).isEmpty()) {
-                    addOrUpdateMemberships = true;
-                }
-            }
-            tasks.addAll(!propByResVirAttr.isEmpty() || addOrUpdateMemberships || removeMemberships
+            tasks.addAll(!propByResVirAttr.isEmpty()
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }
@@ -267,7 +246,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
     @Override
     public List<PropagationStatus> deprovision(final Long userKey, final Collection<String> resources) {
-        final User user = userDAO.authFetch(userKey);
+        final User user = userDAO.authFind(userKey);
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
                 userKey,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
index 58202b7..3ffc1c3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
@@ -26,31 +26,24 @@ import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
+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.user.User;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -71,18 +64,18 @@ public class VirAttrHandler {
     private VirAttrDAO virAttrDAO;
 
     @Autowired
-    private UserDAO userDAO;
+    private AnyObjectDAO anyObjectDAO;
 
     @Autowired
-    private MembershipDAO membershipDAO;
+    private UserDAO userDAO;
 
     @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
+    private AnyUtilsFactory anyUtilsFactory;
 
-    public <T extends VirSchema> T getVirSchema(final String virSchemaName, final Class<T> reference) {
-        T virtualSchema = null;
+    public VirSchema getVirSchema(final String virSchemaName) {
+        VirSchema virtualSchema = null;
         if (StringUtils.isNotBlank(virSchemaName)) {
-            virtualSchema = virSchemaDAO.find(virSchemaName, reference);
+            virtualSchema = virSchemaDAO.find(virSchemaName);
 
             if (virtualSchema == null) {
                 LOG.debug("Ignoring invalid virtual schema {}", virSchemaName);
@@ -92,33 +85,14 @@ public class VirAttrHandler {
         return virtualSchema;
     }
 
-    public void setVirAttrSchema(final Attributable<?, ?, ?> attributable,
-            final VirAttr virAttr, final VirSchema virSchema) {
-
-        if (virAttr instanceof UVirAttr) {
-            ((UVirAttr) virAttr).setSchema((UVirSchema) virSchema);
-        } else if (virAttr instanceof GVirAttr) {
-            GVirAttrTemplate template = ((Group) attributable).
-                    getAttrTemplate(GVirAttrTemplate.class, virSchema.getKey());
-            if (template != null) {
-                ((GVirAttr) virAttr).setTemplate(template);
-            }
-        } else if (virAttr instanceof MVirAttr) {
-            MVirAttrTemplate template =
-                    ((Membership) attributable).getGroup().
-                    getAttrTemplate(MVirAttrTemplate.class, virSchema.getKey());
-            if (template != null) {
-                ((MVirAttr) virAttr).setTemplate(template);
-            }
-        }
-    }
-
-    public void updateOnResourcesIfMappingMatches(final AttributableUtils attrUtils, final String schemaKey,
-            final Set<ExternalResource> resources, final IntMappingType mappingType,
+    public void updateOnResourcesIfMappingMatches(final Any<?, ?, ?> any, final AnyUtils anyUtils,
+            final String schemaKey, final Set<ExternalResource> resources, final IntMappingType mappingType,
             final PropagationByResource propByRes) {
 
         for (ExternalResource resource : resources) {
-            for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+            for (MappingItem mapItem : anyUtils.getMappingItems(
+                    resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
+
                 if (schemaKey.equals(mapItem.getIntAttrName()) && mapItem.getIntMappingType() == mappingType) {
                     propByRes.add(ResourceOperation.UPDATE, resource.getKey());
                 }
@@ -127,44 +101,44 @@ public class VirAttrHandler {
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    public PropagationByResource fillVirtual(final Attributable attributable,
-            final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
-            final AttributableUtils attrUtils) {
+    public PropagationByResource fillVirtual(final Any any,
+            final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated, final AnyUtils anyUtils) {
 
         PropagationByResource propByRes = new PropagationByResource();
 
         Set<ExternalResource> externalResources = new HashSet<>();
-        if (attributable instanceof User) {
-            externalResources.addAll(userDAO.findAllResources((User) attributable));
-        } else if (attributable instanceof Group) {
-            externalResources.addAll(((Group) attributable).getResources());
-        } else if (attributable instanceof Membership) {
-            externalResources.addAll(userDAO.findAllResources(((Membership) attributable).getUser()));
-            externalResources.addAll(((Membership) attributable).getGroup().getResources());
+        if (any instanceof User) {
+            externalResources.addAll(userDAO.findAllResources((User) any));
+        } else if (any instanceof Group) {
+            externalResources.addAll(((Group) any).getResources());
+        } else if (any instanceof AnyObject) {
+            externalResources.addAll(anyObjectDAO.findAllResources((AnyObject) any));
         }
 
         // 1. virtual attributes to be removed
         for (String vAttrToBeRemoved : vAttrsToBeRemoved) {
-            VirSchema virSchema = getVirSchema(vAttrToBeRemoved, attrUtils.virSchemaClass());
+            VirSchema virSchema = getVirSchema(vAttrToBeRemoved);
             if (virSchema != null) {
-                VirAttr virAttr = attributable.getVirAttr(virSchema.getKey());
+                VirAttr virAttr = any.getVirAttr(virSchema.getKey());
                 if (virAttr == null) {
                     LOG.debug("No virtual attribute found for schema {}", virSchema.getKey());
                 } else {
-                    attributable.removeVirAttr(virAttr);
+                    any.remove(virAttr);
                     virAttrDAO.delete(virAttr);
                 }
 
                 for (ExternalResource resource : externalResources) {
-                    for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                            resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
+
                         if (virSchema.getKey().equals(mapItem.getIntAttrName())
-                                && mapItem.getIntMappingType() == attrUtils.virIntMappingType()) {
+                                && mapItem.getIntMappingType() == anyUtils.virIntMappingType()) {
 
                             propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 
-                            // Using virtual attribute as AccountId must be avoided
-                            if (mapItem.isAccountid() && virAttr != null && !virAttr.getValues().isEmpty()) {
-                                propByRes.addOldAccountId(resource.getKey(), virAttr.getValues().get(0));
+                            // Using virtual attribute as ConnObjectKey must be avoided
+                            if (mapItem.isConnObjectKey() && virAttr != null && !virAttr.getValues().isEmpty()) {
+                                propByRes.addOldAccountId(resource.getKey(), virAttr.getValues().get(0).toString());
                             }
                         }
                     }
@@ -176,31 +150,26 @@ public class VirAttrHandler {
 
         // 2. virtual attributes to be updated
         for (AttrMod vAttrToBeUpdated : vAttrsToBeUpdated) {
-            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema(), attrUtils.virSchemaClass());
+            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema());
             VirAttr virAttr = null;
             if (virSchema != null) {
-                virAttr = attributable.getVirAttr(virSchema.getKey());
+                virAttr = any.getVirAttr(virSchema.getKey());
                 if (virAttr == null) {
-                    virAttr = attrUtils.newVirAttr();
-                    setVirAttrSchema(attributable, virAttr, virSchema);
+                    virAttr = anyUtils.newVirAttr();
+                    virAttr.setSchema(virSchema);
                     if (virAttr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema or template was found", vAttrToBeUpdated);
+                        LOG.debug("Ignoring {} because no valid schema was found", vAttrToBeUpdated);
                     } else {
-                        attributable.addVirAttr(virAttr);
+                        any.add(virAttr);
                     }
                 }
             }
 
             if (virSchema != null && virAttr != null && virAttr.getSchema() != null) {
-                if (attributable instanceof Subject) {
-                    updateOnResourcesIfMappingMatches(attrUtils, virSchema.getKey(),
-                            externalResources, attrUtils.derIntMappingType(), propByRes);
-                } else if (attributable instanceof Membership) {
-                    updateOnResourcesIfMappingMatches(attrUtils, virSchema.getKey(),
-                            externalResources, IntMappingType.MembershipVirtualSchema, propByRes);
-                }
+                updateOnResourcesIfMappingMatches(any, anyUtils, virSchema.getKey(),
+                        externalResources, anyUtils.derIntMappingType(), propByRes);
 
-                final List<String> values = new ArrayList<>(virAttr.getValues());
+                List<String> values = new ArrayList<>(virAttr.getValues());
                 values.removeAll(vAttrToBeUpdated.getValuesToBeRemoved());
                 values.addAll(vAttrToBeUpdated.getValuesToBeAdded());
 
@@ -208,7 +177,7 @@ public class VirAttrHandler {
                 virAttr.getValues().addAll(values);
 
                 // Owner cannot be specified before otherwise a virtual attribute remove will be invalidated.
-                virAttr.setOwner(attributable);
+                virAttr.setOwner(any);
             }
         }
 
@@ -220,33 +189,31 @@ public class VirAttrHandler {
     /**
      * Add virtual attributes and specify values to be propagated.
      *
-     * @param attributable attributable.
+     * @param any any.
      * @param vAttrs virtual attributes to be added.
-     * @param attrUtils attributable util.
+     * @param anyUtils utils
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    public void fillVirtual(final Attributable attributable, final Collection<AttrTO> vAttrs,
-            final AttributableUtils attrUtils) {
-
-        for (AttrTO attributeTO : vAttrs) {
-            VirAttr virAttr = attributable.getVirAttr(attributeTO.getSchema());
+    public void fillVirtual(final Any any, final Collection<AttrTO> vAttrs, final AnyUtils anyUtils) {
+        for (AttrTO attrTO : vAttrs) {
+            VirAttr virAttr = any.getVirAttr(attrTO.getSchema());
             if (virAttr == null) {
-                VirSchema virSchema = getVirSchema(attributeTO.getSchema(), attrUtils.virSchemaClass());
+                VirSchema virSchema = getVirSchema(attrTO.getSchema());
                 if (virSchema != null) {
-                    virAttr = attrUtils.newVirAttr();
-                    setVirAttrSchema(attributable, virAttr, virSchema);
+                    virAttr = anyUtils.newVirAttr();
+                    virAttr.setSchema(virSchema);
                     if (virAttr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
+                        LOG.debug("Ignoring {} because no valid schema was found", attrTO);
                     } else {
-                        virAttr.setOwner(attributable);
-                        attributable.addVirAttr(virAttr);
+                        virAttr.setOwner(any);
+                        any.add(virAttr);
                         virAttr.getValues().clear();
-                        virAttr.getValues().addAll(attributeTO.getValues());
+                        virAttr.getValues().addAll(attrTO.getValues());
                     }
                 }
             } else {
                 virAttr.getValues().clear();
-                virAttr.getValues().addAll(attributeTO.getValues());
+                virAttr.getValues().addAll(attrTO.getValues());
             }
         }
     }
@@ -263,50 +230,9 @@ public class VirAttrHandler {
             final Long key, final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated) {
 
         return fillVirtual(
-                userDAO.authFetch(key),
+                anyObjectDAO.authFind(key),
                 vAttrsToBeRemoved,
                 vAttrsToBeUpdated,
-                attrUtilsFactory.getInstance(AttributableType.USER));
+                anyUtilsFactory.getInstance(AnyTypeKind.USER));
     }
-
-    private Set<String> getAttrNames(final List<? extends VirAttr> virAttrs) {
-        final Set<String> virAttrNames = new HashSet<>();
-        for (VirAttr attr : virAttrs) {
-            virAttrNames.add(attr.getSchema().getKey());
-        }
-        return virAttrNames;
-    }
-
-    /**
-     * SYNCOPE-501: build membership virtual attribute changes in case no other changes were made.
-     *
-     * @param key user key
-     * @param groupKey group key
-     * @param membershipKey membership key
-     * @param vAttrsToBeRemoved virtual attributes to be removed.
-     * @param vAttrsToBeUpdated virtual attributes to be updated.
-     * @param isRemoval flag to check if fill is on removed or added membership
-     * @return operations to be performed on external resources for membership virtual attributes changes
-     */
-    public PropagationByResource fillMembershipVirtual(
-            final Long key, final Long groupKey, final Long membershipKey, final Set<String> vAttrsToBeRemoved,
-            final Set<AttrMod> vAttrsToBeUpdated, final boolean isRemoval) {
-
-        Membership membership = membershipKey == null
-                ? userDAO.authFetch(key).getMembership(groupKey)
-                : membershipDAO.authFetch(membershipKey);
-
-        return membership == null ? new PropagationByResource() : isRemoval
-                ? fillVirtual(
-                        membership,
-                        getAttrNames(membership.getVirAttrs()),
-                        vAttrsToBeUpdated,
-                        attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP))
-                : fillVirtual(
-                        membership,
-                        vAttrsToBeRemoved,
-                        vAttrsToBeUpdated,
-                        attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
index faaa070..8ec8e84 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.cache;
 
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
 
@@ -32,12 +31,12 @@ public class DisabledVirAttrCache implements VirAttrCache {
     }
 
     @Override
-    public void expire(final AttributableType type, final Long id, final String schemaName) {
+    public void expire(final String type, final Long id, final String schemaName) {
         // nothing to do
     }
 
     @Override
-    public VirAttrCacheValue get(final AttributableType type, final Long id, final String schemaName) {
+    public VirAttrCacheValue get(final String type, final Long id, final String schemaName) {
         return null;
     }
 
@@ -47,9 +46,7 @@ public class DisabledVirAttrCache implements VirAttrCache {
     }
 
     @Override
-    public void put(
-            final AttributableType type, final Long id, final String schemaName, final VirAttrCacheValue value) {
-
+    public void put(final String type, final Long id, final String schemaName, final VirAttrCacheValue value) {
         // nothing to do
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
index 885b194..bac145e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
@@ -23,7 +23,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheKey;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
@@ -56,14 +55,14 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Cache virtual attribute values.
      *
-     * @param type user, group or membership
+     * @param type any object type
      * @param key attributable key
      * @param schemaName virtual attribute name
      * @param value virtual attribute values
      */
     @Override
     public void put(
-            final AttributableType type,
+            final String type,
             final Long key,
             final String schemaName,
             final VirAttrCacheValue value) {
@@ -81,25 +80,25 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Retrieve cached value. Return null in case of virtual attribute not cached.
      *
-     * @param type user, group or membership
+     * @param type any object type
      * @param key attributable key
      * @param schemaName virtual attribute schema name.
      * @return cached values or null if virtual attribute is not cached.
      */
     @Override
-    public VirAttrCacheValue get(final AttributableType type, final Long key, final String schemaName) {
+    public VirAttrCacheValue get(final String type, final Long key, final String schemaName) {
         return cache.get(new VirAttrCacheKey(type, key, schemaName));
     }
 
     /**
      * Force entry expiring.
      *
-     * @param type user, group or membership
+     * @param type any object type
      * @param key attributable key
      * @param schemaName virtual attribute schema name
      */
     @Override
-    public void expire(final AttributableType type, final Long key, final String schemaName) {
+    public void expire(final String type, final Long key, final String schemaName) {
         final VirAttrCacheValue value = cache.get(new VirAttrCacheKey(type, key, schemaName));
         if (isValidEntry(value)) {
             synchronized (cache) {


[07/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
index ae6d8a8..eec346e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
@@ -18,18 +18,30 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
 import org.apache.syncope.common.lib.to.NotificationTO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class NotificationDataBinderImpl implements NotificationDataBinder {
 
-    private static final String[] IGNORE_PROPERTIES = { "key", "about", "recipients" };
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationDataBinder.class);
+
+    private static final String[] IGNORE_PROPERTIES = { "key", "abouts", "recipients" };
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
 
     @Autowired
     private EntityFactory entityFactory;
@@ -41,8 +53,10 @@ public class NotificationDataBinderImpl implements NotificationDataBinder {
         BeanUtils.copyProperties(notification, result, IGNORE_PROPERTIES);
 
         result.setKey(notification.getKey());
-        result.setUserAbout(notification.getUserAbout());
-        result.setGroupAbout(notification.getGroupAbout());
+        for (AnyAbout about : notification.getAbouts()) {
+            result.getAbouts().put(about.getAnyType().getKey(), about.get());
+        }
+
         result.setRecipients(notification.getRecipients());
 
         return result;
@@ -59,8 +73,22 @@ public class NotificationDataBinderImpl implements NotificationDataBinder {
     public void update(final Notification notification, final NotificationTO notificationTO) {
         BeanUtils.copyProperties(notificationTO, notification, IGNORE_PROPERTIES);
 
-        notification.setUserAbout(notificationTO.getUserAbout());
-        notification.setGroupAbout(notificationTO.getGroupAbout());
+        notification.getAbouts().clear();
+        for (Map.Entry<String, String> entry : notificationTO.getAbouts().entrySet()) {
+            if (StringUtils.isNotBlank(entry.getValue())) {
+                AnyType anyType = anyTypeDAO.find(entry.getKey());
+                if (anyType == null) {
+                    LOG.warn("Invalid AnyType {} specified, ignoring...", entry.getKey());
+                } else {
+                    AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+                    about.setAnyType(anyType);
+                    about.setNotification(notification);
+
+                    notification.add(about);
+                }
+            }
+        }
+
         notification.setRecipients(notificationTO.getRecipients());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index 3fe382c..b29f9fa 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -32,7 +32,7 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Realm;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index cf1339e..fae0f9f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -27,6 +27,7 @@ import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IntMappingType;
@@ -36,34 +37,34 @@ import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 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.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+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.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+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.resource.Provision;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class ResourceDataBinderImpl implements ResourceDataBinder {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ResourceDataBinder.class);
 
     private static final String[] MAPPINGITEM_IGNORE_PROPERTIES = { "key", "mapping" };
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private ConnectorRegistry connRegistry;
 
     @Autowired
@@ -107,21 +108,34 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         resource.setPropagationMode(resourceTO.getPropagationMode());
 
-        if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
-            resource.setUmapping(null);
-        } else {
-            UMapping mapping = entityFactory.newEntity(UMapping.class);
-            mapping.setResource(resource);
-            resource.setUmapping(mapping);
-            populateMapping(resourceTO.getUmapping(), mapping, entityFactory.newEntity(UMappingItem.class));
-        }
-        if (resourceTO.getGmapping() == null || resourceTO.getGmapping().getItems().isEmpty()) {
-            resource.setGmapping(null);
-        } else {
-            GMapping mapping = entityFactory.newEntity(GMapping.class);
-            mapping.setResource(resource);
-            resource.setGmapping(mapping);
-            populateMapping(resourceTO.getGmapping(), mapping, entityFactory.newEntity(GMappingItem.class));
+        for (ProvisionTO provisionTO : resourceTO.getProvisions()) {
+            AnyType anyType = anyTypeDAO.find(provisionTO.getAnyType());
+            if (anyType == null) {
+                LOG.warn("Invalid type specified {}, ignoring...", provisionTO.getAnyType());
+            }
+
+            Provision provision = resource.getProvision(anyType);
+            if (provision == null) {
+                provision = entityFactory.newEntity(Provision.class);
+                provision.setResource(resource);
+                resource.add(provision);
+                provision.setAnyType(anyType);
+            }
+
+            provision.setObjectClass(new ObjectClass(provisionTO.getObjectClass()));
+
+            if (provisionTO.getSyncToken() == null) {
+                provision.setSyncToken(null);
+            }
+
+            if (provisionTO.getMapping() == null) {
+                provision.setMapping(null);
+            } else {
+                Mapping mapping = entityFactory.newEntity(Mapping.class);
+                mapping.setProvision(provision);
+                provision.setMapping(mapping);
+                populateMapping(provisionTO.getMapping(), mapping, entityFactory.newEntity(MappingItem.class));
+            }
         }
 
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
@@ -140,13 +154,6 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         resource.setConnInstanceConfiguration(new HashSet<>(resourceTO.getConnConfProperties()));
 
-        if (resourceTO.getUsyncToken() == null) {
-            resource.setUsyncToken(null);
-        }
-        if (resourceTO.getRsyncToken() == null) {
-            resource.setRsyncToken(null);
-        }
-
         resource.getPropagationActionsClassNames().clear();
         resource.getPropagationActionsClassNames().addAll(resourceTO.getPropagationActionsClassNames());
 
@@ -155,16 +162,14 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
     private void populateMapping(final MappingTO mappingTO, final Mapping mapping, final MappingItem prototype) {
-        mapping.setAccountLink(mappingTO.getAccountLink());
+        mapping.setConnObjectLink(mappingTO.getConnObjectLink());
 
         for (MappingItem item : getMappingItems(mappingTO.getItems(), prototype)) {
             item.setMapping(mapping);
-            if (item.isAccountid()) {
-                mapping.setAccountIdItem(item);
-            } else if (item.isPassword()) {
-                ((UMapping) mapping).setPasswordItem((UMappingItem) item);
+            if (item.isConnObjectKey()) {
+                mapping.setConnObjectKeyItem(item);
             } else {
-                mapping.addItem(item);
+                mapping.add(item);
             }
         }
     }
@@ -233,8 +238,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         return connRegistry.getOverriddenConnInstance(connInstanceClone, resourceTO.getConnConfProperties());
     }
 
-    private void populateMappingTO(final Mapping<?> mapping, final MappingTO mappingTO) {
-        mappingTO.setAccountLink(mapping.getAccountLink());
+    private void populateMappingTO(final Mapping mapping, final MappingTO mappingTO) {
+        mappingTO.setConnObjectLink(mapping.getConnObjectLink());
 
         for (MappingItem item : mapping.getItems()) {
             MappingItemTO itemTO = new MappingItemTO();
@@ -242,11 +247,9 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
 
             if (itemTO.isAccountid()) {
-                mappingTO.setAccountIdItem(itemTO);
-            } else if (itemTO.isPassword()) {
-                mappingTO.setPasswordItem(itemTO);
+                mappingTO.setConnObjectKeyItem(itemTO);
             } else {
-                mappingTO.addItem(itemTO);
+                mappingTO.add(itemTO);
             }
         }
     }
@@ -274,16 +277,19 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         resourceTO.setConnectorId(connector == null ? null : connector.getKey());
         resourceTO.setConnectorDisplayName(connector == null ? null : connector.getDisplayName());
 
-        // set the mappings
-        if (resource.getUmapping() != null) {
-            MappingTO mappingTO = new MappingTO();
-            resourceTO.setUmapping(mappingTO);
-            populateMappingTO(resource.getUmapping(), mappingTO);
-        }
-        if (resource.getGmapping() != null) {
-            MappingTO mappingTO = new MappingTO();
-            resourceTO.setGmapping(mappingTO);
-            populateMappingTO(resource.getGmapping(), mappingTO);
+        // set the provision information
+        for (Provision provision : resource.getProvisions()) {
+            ProvisionTO provisionTO = new ProvisionTO();
+            provisionTO.setKey(provision.getKey());
+            provisionTO.setAnyType(provision.getAnyType().getKey());
+            provisionTO.setObjectClass(provision.getObjectClass().getObjectClassValue());
+            provisionTO.setSyncToken(provision.getSerializedSyncToken());
+
+            if (provision.getMapping() != null) {
+                MappingTO mappingTO = new MappingTO();
+                provisionTO.setMapping(mappingTO);
+                populateMappingTO(provision.getMapping(), mappingTO);
+            }
         }
 
         resourceTO.setEnforceMandatoryCondition(resource.isEnforceMandatoryCondition());
@@ -312,9 +318,6 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         resourceTO.getConnConfProperties().addAll(resource.getConnInstanceConfiguration());
 
-        resourceTO.setUsyncToken(resource.getSerializedUSyncToken());
-        resourceTO.setRsyncToken(resource.getSerializedRSyncToken());
-
         resourceTO.getPropagationActionsClassNames().addAll(resource.getPropagationActionsClassNames());
 
         return resourceTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
index 2f4fd2d..b286043 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
@@ -26,10 +26,10 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 import org.apache.syncope.core.provisioning.api.data.RoleDataBinder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -101,7 +101,7 @@ public class RoleDataBinderImpl implements RoleDataBinder {
             } else if (role.getDynMembership() != null && roleTO.getDynMembershipCond() != null
                     && !role.getDynMembership().getFIQLCond().equals(roleTO.getDynMembershipCond())) {
 
-                role.getDynMembership().getUsers().clear();
+                role.getDynMembership().getMembers().clear();
                 setDynMembership(role, roleTO.getDynMembershipCond());
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index 0a34e61..e44198b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -19,22 +19,22 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
-import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -44,6 +44,9 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
     @Autowired
     private PlainSchemaDAO schemaDAO;
 
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
     // --------------- PLAIN -----------------
     private <T extends PlainSchema> void fill(final T schema, final PlainSchemaTO schemaTO) {
         if (!JexlUtils.isExpressionValid(schemaTO.getMandatoryCondition())) {
@@ -61,13 +64,16 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
     }
 
     @Override
-    public <T extends PlainSchema> void update(final PlainSchemaTO schemaTO, final T schema,
-            final AttributableUtils attributableUtil) {
-
+    public <T extends PlainSchema> void update(final PlainSchemaTO schemaTO, final T schema) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
-        List<PlainAttr> attrs = schemaDAO.findAttrs(schema, attributableUtil.plainAttrClass());
-        if (!attrs.isEmpty()) {
+        boolean hasAttrs = false;
+        for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
+            hasAttrs &= schemaDAO.findAttrs(schema, anyUtils.plainAttrClass()).isEmpty();
+        }
+
+        if (hasAttrs) {
             if (schema.getType() != schemaTO.getType()) {
                 SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidPlainSchema);
                 e.getElements().add("Cannot change type since " + schema.getKey() + " has attributes");
@@ -90,9 +96,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
     }
 
     @Override
-    public <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(
-            final T schema, final AttributableUtils attributableUtil) {
-
+    public <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(final T schema) {
         PlainSchemaTO schemaTO = new PlainSchemaTO();
         BeanUtils.copyProperties(schema, schemaTO);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 9fe733e..c25b3ed 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -18,14 +18,14 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import java.util.Map;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
 import org.apache.syncope.common.lib.to.AbstractProvisioningTaskTO;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -40,7 +40,6 @@ import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
@@ -53,7 +52,13 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -87,16 +92,22 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     private TaskExecDAO taskExecDAO;
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
     private SchedulerFactoryBean scheduler;
 
-    private void checkJexl(final AbstractAttributableTO attributableTO, final SyncopeClientException sce) {
-        for (AttrTO attrTO : attributableTO.getPlainAttrs()) {
+    private void checkJexl(final AnyTO anyTO, final SyncopeClientException sce) {
+        for (AttrTO attrTO : anyTO.getPlainAttrs()) {
             if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
                 sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
             }
         }
 
-        for (AttrTO attrTO : attributableTO.getVirAttrs()) {
+        for (AttrTO attrTO : anyTO.getVirAttrs()) {
             if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
                 sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
             }
@@ -105,11 +116,17 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
     private void fill(final ProvisioningTask task, final AbstractProvisioningTaskTO taskTO) {
         if (task instanceof PushTask && taskTO instanceof PushTaskTO) {
-            final PushTask pushTask = (PushTask) task;
-            final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
+            PushTask pushTask = (PushTask) task;
+            PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
+
+            for (Map.Entry<String, String> entry : pushTaskTO.getFilters().entrySet()) {
+                AnyFilter filter = entityFactory.newEntity(AnyFilter.class);
+                filter.setAnyType(anyTypeDAO.find(entry.getKey()));
+                filter.set(entry.getValue());
 
-            pushTask.setUserFilter(pushTaskTO.getUserFilter());
-            pushTask.setGroupFilter(pushTaskTO.getGroupFilter());
+                filter.setPushTask(pushTask);
+                pushTask.add(filter);
+            }
 
             pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
                     ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
@@ -131,42 +148,46 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSyncTask);
             // 1. validate JEXL expressions in user and group templates
-            if (syncTaskTO.getUserTemplate() != null) {
-                UserTO template = syncTaskTO.getUserTemplate();
-
-                if (StringUtils.isNotBlank(template.getUsername())
-                        && !JexlUtils.isExpressionValid(template.getUsername())) {
-
-                    sce.getElements().add("Invalid JEXL: " + template.getUsername());
-                }
-                if (StringUtils.isNotBlank(template.getPassword())
-                        && !JexlUtils.isExpressionValid(template.getPassword())) {
-
-                    sce.getElements().add("Invalid JEXL: " + template.getPassword());
-                }
-
-                checkJexl(template, sce);
-
-                for (MembershipTO memb : template.getMemberships()) {
-                    checkJexl(memb, sce);
+            for (Map.Entry<String, AnyTO> entry : syncTaskTO.getTemplates().entrySet()) {
+                checkJexl(entry.getValue(), sce);
+
+                if (entry.getValue() instanceof UserTO) {
+                    UserTO template = (UserTO) entry.getValue();
+                    if (StringUtils.isNotBlank(template.getUsername())
+                            && !JexlUtils.isExpressionValid(template.getUsername())) {
+
+                        sce.getElements().add("Invalid JEXL: " + template.getUsername());
+                    }
+                    if (StringUtils.isNotBlank(template.getPassword())
+                            && !JexlUtils.isExpressionValid(template.getPassword())) {
+
+                        sce.getElements().add("Invalid JEXL: " + template.getPassword());
+                    }
+                } else if (entry.getValue() instanceof GroupTO) {
+                    GroupTO template = (GroupTO) entry.getValue();
+                    if (StringUtils.isNotBlank(template.getName())
+                            && !JexlUtils.isExpressionValid(template.getName())) {
+
+                        sce.getElements().add("Invalid JEXL: " + template.getName());
+                    }
                 }
             }
-            if (syncTaskTO.getGroupTemplate() != null) {
-                GroupTO template = syncTaskTO.getGroupTemplate();
-
-                if (StringUtils.isNotBlank(template.getName()) && !JexlUtils.isExpressionValid(template.getName())) {
-                    sce.getElements().add("Invalid JEXL: " + template.getName());
-                }
-
-                checkJexl(template, sce);
-            }
             if (!sce.isEmpty()) {
                 throw sce;
             }
 
             // 2. all JEXL expressions are valid: accept user and group templates
-            syncTask.setUserTemplate(syncTaskTO.getUserTemplate());
-            syncTask.setGroupTemplate(syncTaskTO.getGroupTemplate());
+            for (Map.Entry<String, AnyTO> entry : syncTaskTO.getTemplates().entrySet()) {
+                AnyType type = anyTypeDAO.find(entry.getKey());
+                if (type != null) {
+                    AnyTemplate anyTemplate = entityFactory.newEntity(AnyTemplate.class);
+                    anyTemplate.setAnyType(type);
+                    anyTemplate.set(entry.getValue());
+                    anyTemplate.setSyncTask(syncTask);
+
+                    syncTask.add(anyTemplate);
+                }
+            }
 
             syncTask.setFullReconciliation(syncTaskTO.isFullReconciliation());
         }
@@ -176,12 +197,16 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         task.setPerformUpdate(taskTO.isPerformUpdate());
         task.setPerformDelete(taskTO.isPerformDelete());
         task.setSyncStatus(taskTO.isSyncStatus());
-        task.getActionsClassNames().clear();
-        task.getActionsClassNames().addAll(taskTO.getActionsClassNames());
+        task.getActionsClassNames()
+                .clear();
+        task.getActionsClassNames()
+                .addAll(taskTO.getActionsClassNames());
     }
 
     @Override
-    public SchedTask createSchedTask(final SchedTaskTO taskTO, final TaskUtils taskUtils) {
+    public SchedTask createSchedTask(final SchedTaskTO taskTO,
+            final TaskUtils taskUtils
+    ) {
         final Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
 
         if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
@@ -212,7 +237,10 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     }
 
     @Override
-    public void updateSchedTask(final SchedTask task, final SchedTaskTO taskTO, final TaskUtils taskUtils) {
+    public void updateSchedTask(final SchedTask task,
+            final SchedTaskTO taskTO,
+            final TaskUtils taskUtils
+    ) {
         Class<? extends Task> taskClass = taskUtils.taskClass();
         Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
 
@@ -240,7 +268,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     }
 
     @Override
-    public TaskExecTO getTaskExecTO(final TaskExec execution) {
+    public TaskExecTO getTaskExecTO(final TaskExec execution
+    ) {
         TaskExecTO executionTO = new TaskExecTO();
         BeanUtils.copyProperties(execution, executionTO, IGNORE_TASK_EXECUTION_PROPERTIES);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index 317fce2..e7ec3cd 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Map;
@@ -31,24 +30,15 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-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.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -60,13 +50,14 @@ import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 @Component
 @Transactional(rollbackFor = { Throwable.class })
-public class UserDataBinderImpl extends AbstractAttributableDataBinder implements UserDataBinder {
+public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDataBinder {
 
     private static final String[] IGNORE_USER_PROPERTIES = {
         "realm", "roles", "memberships", "plainAttrs", "derAttrs", "virAttrs", "resources",
@@ -118,7 +109,7 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
     @Transactional(readOnly = true)
     @Override
     public boolean verifyPassword(final String username, final String password) {
-        return verifyPassword(userDAO.authFetch(username), password);
+        return verifyPassword(userDAO.authFind(username), password);
     }
 
     @Transactional(readOnly = true)
@@ -153,40 +144,35 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
             if (role == null) {
                 LOG.warn("Ignoring unknown role with id {}", roleKey);
             } else {
-                user.addRole(role);
+                user.add(role);
             }
         }
 
         // memberships
-        Group group;
         for (MembershipTO membershipTO : userTO.getMemberships()) {
-            group = groupDAO.find(membershipTO.getGroupKey());
+            Group group = groupDAO.find(membershipTO.getRightKey());
 
             if (group == null) {
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
                 }
             } else {
-                Membership membership = null;
+                UMembership membership = null;
                 if (user.getKey() != null) {
-                    membership = user.getMembership(group.getKey()) == null
-                            ? membershipDAO.find(user, group)
-                            : user.getMembership(group.getKey());
+                    membership = user.getMembership(group.getKey());
                 }
                 if (membership == null) {
-                    membership = entityFactory.newEntity(Membership.class);
-                    membership.setGroup(group);
-                    membership.setUser(user);
+                    membership = entityFactory.newEntity(UMembership.class);
+                    membership.setRightEnd(group);
+                    membership.setLeftEnd(user);
 
-                    user.addMembership(membership);
+                    user.add(membership);
                 }
-
-                fill(membership, membershipTO, attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP), scce);
             }
         }
 
         // realm, attributes, derived attributes, virtual attributes and resources
-        fill(user, userTO, attrUtilsFactory.getInstance(AttributableType.USER), scce);
+        fill(user, userTO, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce);
 
         // set password
         if (StringUtils.isBlank(userTO.getPassword()) || !storePassword) {
@@ -228,7 +214,7 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
         Collection<String> currentResources = userDAO.findAllResourceNames(user);
 
         // fetch account ids before update
-        Map<String, String> oldAccountIds = getAccountIds(user, AttributableType.USER);
+        Map<String, String> oldConnObjectKeys = getConnObjectKeys(user);
 
         // realm
         setRealm(user, userMod);
@@ -272,7 +258,7 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
                 if (role == null) {
                     LOG.warn("Ignoring unknown role with id {}", roleKey);
                 } else {
-                    user.removeRole(role);
+                    user.remove(role);
                 }
             }
         });
@@ -284,100 +270,57 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
                 if (role == null) {
                     LOG.warn("Ignoring unknown role with id {}", roleKey);
                 } else {
-                    user.addRole(role);
+                    user.add(role);
                 }
             }
         });
 
         // attributes, derived attributes, virtual attributes and resources
-        propByRes.merge(fill(user, userMod, attrUtilsFactory.getInstance(AttributableType.USER), scce));
+        propByRes.merge(fill(user, userMod, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce));
 
         // store the group ids of membership required to be added
-        Set<Long> membershipToBeAddedGroupKeys = CollectionUtils.collect(userMod.getMembershipsToAdd(),
-                new Transformer<MembershipMod, Long>() {
-
-                    @Override
-                    public Long transform(final MembershipMod membToBeAdded) {
-                        return membToBeAdded.getGroup();
-                    }
-                }, new HashSet<Long>());
+        Set<Long> membershipToBeAddedGroupKeys = new HashSet<>(userMod.getMembershipsToAdd());
 
         final Set<String> toBeDeprovisioned = new HashSet<>();
         final Set<String> toBeProvisioned = new HashSet<>();
 
         // memberships to be removed
-        for (Long membKey : userMod.getMembershipsToRemove()) {
-            LOG.debug("Membership to be removed: {}", membKey);
+        for (Long groupKey : userMod.getMembershipsToRemove()) {
+            LOG.debug("Membership to be removed for group {}", groupKey);
 
-            Membership membership = membershipDAO.find(membKey);
+            UMembership membership = user.getMembership(groupKey);
             if (membership == null) {
-                LOG.warn("Invalid membership id specified to be removed: {}", membKey);
+                LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey);
             } else {
-                if (!membershipToBeAddedGroupKeys.contains(membership.getGroup().getKey())) {
-                    toBeDeprovisioned.addAll(membership.getGroup().getResourceNames());
+                if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
+                    toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
 
-                // In order to make the removeMembership() below to work,
-                // we need to be sure to take exactly the same membership
-                // of the user object currently in memory (which has potentially
-                // some modifications compared to the one stored in the DB
-                membership = user.getMembership(membership.getGroup().getKey());
-                if (membershipToBeAddedGroupKeys.contains(membership.getGroup().getKey())) {
-                    Set<Long> attrKeys = new HashSet<>(membership.getPlainAttrs().size());
-                    for (PlainAttr plainAttr : membership.getPlainAttrs()) {
-                        attrKeys.add(plainAttr.getKey());
-                    }
-                    for (Long attrKey : attrKeys) {
-                        plainAttrDAO.delete(attrKey, MPlainAttr.class);
-                    }
-                    attrKeys.clear();
-
-                    // remove derived attributes
-                    for (DerAttr derAttr : membership.getDerAttrs()) {
-                        attrKeys.add(derAttr.getKey());
-                    }
-                    for (Long derAttrId : attrKeys) {
-                        derAttrDAO.delete(derAttrId, MDerAttr.class);
-                    }
-                    attrKeys.clear();
-
-                    // remove virtual attributes
-                    for (VirAttr virAttr : membership.getVirAttrs()) {
-                        attrKeys.add(virAttr.getKey());
-                    }
-                    for (Long virAttrId : attrKeys) {
-                        virAttrDAO.delete(virAttrId, MVirAttr.class);
-                    }
-                    attrKeys.clear();
+                if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
                 } else {
-                    user.removeMembership(membership);
-
-                    membershipDAO.delete(membKey);
+                    user.remove(membership);
                 }
             }
         }
 
         // memberships to be added
-        for (MembershipMod membershipMod : userMod.getMembershipsToAdd()) {
-            LOG.debug("Membership to be added: group({})", membershipMod.getGroup());
+        for (Long groupKey : userMod.getMembershipsToAdd()) {
+            LOG.debug("Membership to be added for group {}", groupKey);
 
-            Group group = groupDAO.find(membershipMod.getGroup());
+            Group group = groupDAO.find(groupKey);
             if (group == null) {
-                LOG.debug("Ignoring invalid group {}", membershipMod.getGroup());
+                LOG.debug("Ignoring invalid group {}", groupKey);
             } else {
-                Membership membership = user.getMembership(group.getKey());
+                UMembership membership = user.getMembership(group.getKey());
                 if (membership == null) {
-                    membership = entityFactory.newEntity(Membership.class);
-                    membership.setGroup(group);
-                    membership.setUser(user);
+                    membership = entityFactory.newEntity(UMembership.class);
+                    membership.setRightEnd(group);
+                    membership.setLeftEnd(user);
 
-                    user.addMembership(membership);
+                    user.add(membership);
 
                     toBeProvisioned.addAll(group.getResourceNames());
                 }
-
-                propByRes.merge(fill(membership, membershipMod,
-                        attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP), scce));
             }
         }
 
@@ -394,8 +337,8 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
         }
 
         // check if some account id was changed by the update above
-        Map<String, String> newAccountIds = getAccountIds(user, AttributableType.USER);
-        for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) {
+        Map<String, String> newAccountIds = getConnObjectKeys(user);
+        for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) {
             if (newAccountIds.containsKey(entry.getKey())
                     && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) {
 
@@ -418,29 +361,16 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
             userTO.setSecurityQuestion(user.getSecurityQuestion().getKey());
         }
 
-        connObjectUtils.retrieveVirAttrValues(user, attrUtilsFactory.getInstance(AttributableType.USER));
+        connObjectUtils.retrieveVirAttrValues(user);
         fillTO(userTO, user.getRealm().getFullPath(),
                 user.getPlainAttrs(), user.getDerAttrs(), user.getVirAttrs(), userDAO.findAllResources(user));
 
-        for (Membership membership : user.getMemberships()) {
+        for (UMembership membership : user.getMemberships()) {
             MembershipTO membershipTO = new MembershipTO();
 
-            // set sys info
-            membershipTO.setCreator(membership.getCreator());
-            membershipTO.setCreationDate(membership.getCreationDate());
-            membershipTO.setLastModifier(membership.getLastModifier());
-            membershipTO.setLastChangeDate(membership.getLastChangeDate());
-
             membershipTO.setKey(membership.getKey());
-            membershipTO.setGroupKey(membership.getGroup().getKey());
-            membershipTO.setGroupName(membership.getGroup().getName());
-
-            // SYNCOPE-458 retrieve also membership virtual attributes
-            connObjectUtils.retrieveVirAttrValues(
-                    membership, attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
-            fillTO(membershipTO, null,
-                    membership.getPlainAttrs(), membership.getDerAttrs(), membership.getVirAttrs(),
-                    Collections.<ExternalResource>emptyList());
+            membershipTO.setRightKey(membership.getRightEnd().getKey());
+            membershipTO.setGroupName(membership.getRightEnd().getName());
 
             userTO.getMemberships().add(membershipTO);
         }
@@ -467,13 +397,13 @@ public class UserDataBinderImpl extends AbstractAttributableDataBinder implement
     @Transactional(readOnly = true)
     @Override
     public UserTO getUserTO(final String username) {
-        return getUserTO(userDAO.authFetch(username));
+        return getUserTO(userDAO.authFind(username));
     }
 
     @Transactional(readOnly = true)
     @Override
     public UserTO getUserTO(final Long key) {
-        return getUserTO(userDAO.authFetch(key));
+        return getUserTO(userDAO.authFind(key));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 7153529..776b8db 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -30,26 +30,21 @@ import java.util.Set;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.AuditLoggerName;
 import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.CollectionUtils2;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 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.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
@@ -61,6 +56,12 @@ import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.context.Context;
@@ -100,6 +101,12 @@ public class NotificationManagerImpl implements NotificationManager {
     private ConfDAO confDAO;
 
     /**
+     * AnyObject DAO.
+     */
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    /**
      * User DAO.
      */
     @Autowired
@@ -112,10 +119,10 @@ public class NotificationManagerImpl implements NotificationManager {
     private GroupDAO groupDAO;
 
     /**
-     * User Search DAO.
+     * Search DAO.
      */
     @Autowired
-    private SubjectSearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     /**
      * Task DAO.
@@ -148,7 +155,7 @@ public class NotificationManagerImpl implements NotificationManager {
     private EntityFactory entityFactory;
 
     @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
+    private AnyUtilsFactory anyUtilsFactory;
 
     @Transactional(readOnly = true)
     @Override
@@ -160,19 +167,17 @@ public class NotificationManagerImpl implements NotificationManager {
      * Create a notification task.
      *
      * @param notification notification to take as model
-     * @param attributable the user this task is about
+     * @param any the any object this task is about
      * @param model Velocity model
      * @return notification task, fully populated
      */
     private NotificationTask getNotificationTask(
             final Notification notification,
-            final Attributable<?, ?, ?> attributable,
+            final Any<?, ?, ?> any,
             final Map<String, Object> model) {
 
-        if (attributable != null) {
-            connObjectUtils.retrieveVirAttrValues(attributable,
-                    attrUtilsFactory.getInstance(
-                            attributable instanceof User ? AttributableType.USER : AttributableType.GROUP));
+        if (any != null) {
+            connObjectUtils.retrieveVirAttrValues(any);
         }
 
         final List<User> recipients = new ArrayList<>();
@@ -180,17 +185,17 @@ public class NotificationManagerImpl implements NotificationManager {
         if (notification.getRecipients() != null) {
             recipients.addAll(searchDAO.<User>search(SyncopeConstants.FULL_ADMIN_REALMS,
                     SearchCondConverter.convert(notification.getRecipients()),
-                    Collections.<OrderByClause>emptyList(), SubjectType.USER));
+                    Collections.<OrderByClause>emptyList(), AnyTypeKind.USER));
         }
 
-        if (notification.isSelfAsRecipient() && attributable instanceof User) {
-            recipients.add((User) attributable);
+        if (notification.isSelfAsRecipient() && any instanceof User) {
+            recipients.add((User) any);
         }
 
         final Set<String> recipientEmails = new HashSet<>();
         final List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
         for (User recipient : recipients) {
-            connObjectUtils.retrieveVirAttrValues(recipient, attrUtilsFactory.getInstance(AttributableType.USER));
+            connObjectUtils.retrieveVirAttrValues(recipient);
 
             String email = getRecipientEmail(notification.getRecipientAttrType(),
                     notification.getRecipientAttrName(), recipient);
@@ -266,42 +271,42 @@ public class NotificationManagerImpl implements NotificationManager {
             final Object output,
             final Object... input) {
 
-        SubjectType subjectType = null;
-        Subject<?, ?, ?> subject = null;
+        Any<?, ?, ?> any = null;
 
         if (before instanceof UserTO) {
-            subjectType = SubjectType.USER;
-            subject = userDAO.find(((UserTO) before).getKey());
+            any = userDAO.find(((UserTO) before).getKey());
         } else if (output instanceof UserTO) {
-            subjectType = SubjectType.USER;
-            subject = userDAO.find(((UserTO) output).getKey());
+            any = userDAO.find(((UserTO) output).getKey());
+        } else if (before instanceof AnyObjectTO) {
+            any = anyObjectDAO.find(((AnyObjectTO) before).getKey());
+        } else if (output instanceof AnyObjectTO) {
+            any = anyObjectDAO.find(((AnyObjectTO) output).getKey());
         } else if (before instanceof GroupTO) {
-            subjectType = SubjectType.GROUP;
-            subject = groupDAO.find(((GroupTO) before).getKey());
+            any = groupDAO.find(((GroupTO) before).getKey());
         } else if (output instanceof GroupTO) {
-            subjectType = SubjectType.GROUP;
-            subject = groupDAO.find(((GroupTO) output).getKey());
+            any = groupDAO.find(((GroupTO) output).getKey());
         }
 
-        LOG.debug("Search notification for [{}]{}", subjectType, subject);
+        AnyType anyType = any == null ? null : any.getType();
+        LOG.debug("Search notification for [{}]{}", anyType, any);
 
         for (Notification notification : notificationDAO.findAll()) {
-            LOG.debug("Notification available user about {}", notification.getUserAbout());
-            LOG.debug("Notification available group about {}", notification.getGroupAbout());
+            if (LOG.isDebugEnabled()) {
+                for (AnyAbout about : notification.getAbouts()) {
+                    LOG.debug("Notification about {} defined: {}", about.getAnyType(), about.get());
+                }
+            }
 
             if (notification.isActive()) {
                 String currentEvent = AuditLoggerName.buildEvent(type, category, subcategory, event, condition);
                 if (!notification.getEvents().contains(currentEvent)) {
-                    LOG.debug("No events found about {}", subject);
-                } else if (subjectType == null || subject == null
-                        || (subjectType == SubjectType.USER && (notification.getUserAbout() == null
-                        || searchDAO.matches(subject,
-                                SearchCondConverter.convert(notification.getUserAbout()), subjectType)))
-                        || subjectType == SubjectType.GROUP && (notification.getGroupAbout() == null
-                        || searchDAO.matches(subject,
-                                SearchCondConverter.convert(notification.getGroupAbout()), subjectType))) {
+                    LOG.debug("No events found about {}", any);
+                } else if (anyType == null || any == null
+                        || notification.getAbout(anyType) == null
+                        || searchDAO.matches(any,
+                                SearchCondConverter.convert(notification.getAbout(anyType).get()), anyType.getKind())) {
 
-                    LOG.debug("Creating notification task for event {} about {}", currentEvent, subject);
+                    LOG.debug("Creating notification task for event {} about {}", currentEvent, any);
 
                     final Map<String, Object> model = new HashMap<>();
                     model.put("type", type);
@@ -313,18 +318,16 @@ public class NotificationManagerImpl implements NotificationManager {
                     model.put("output", output);
                     model.put("input", input);
 
-                    if (subject instanceof User) {
-                        model.put("user", userDataBinder.getUserTO((User) subject));
-                    } else if (subject instanceof Group) {
-                        model.put("group", groupDataBinder.getGroupTO((Group) subject));
+                    if (any instanceof User) {
+                        model.put("user", userDataBinder.getUserTO((User) any));
+                    } else if (any instanceof Group) {
+                        model.put("group", groupDataBinder.getGroupTO((Group) any));
                     }
 
-                    taskDAO.save(getNotificationTask(notification, subject, model));
+                    taskDAO.save(getNotificationTask(notification, any, model));
                 }
             } else {
-                LOG.debug("Notification {}, userAbout {}, groupAbout {} is deactivated, "
-                        + "notification task will not be created", notification.getKey(),
-                        notification.getUserAbout(), notification.getGroupAbout());
+                LOG.debug("Notification {} is not active, task will not be created", notification.getKey());
             }
         }
     }
@@ -342,7 +345,7 @@ public class NotificationManagerImpl implements NotificationManager {
             case UserPlainSchema:
                 UPlainAttr attr = user.getPlainAttr(recipientAttrName);
                 if (attr != null) {
-                    email = CollectionUtils2.getFirstOrNull(attr.getValuesAsStrings());
+                    email = attr.getValuesAsStrings().isEmpty() ? null : attr.getValuesAsStrings().get(0);
                 }
                 break;
 
@@ -356,7 +359,7 @@ public class NotificationManagerImpl implements NotificationManager {
             case UserVirtualSchema:
                 UVirAttr virAttr = user.getVirAttr(recipientAttrName);
                 if (virAttr != null) {
-                    email = CollectionUtils2.getFirstOrNull(virAttr.getValues());
+                    email = virAttr.getValues().isEmpty() ? null : virAttr.getValues().get(0);
                 }
                 break;
 
@@ -402,7 +405,7 @@ public class NotificationManagerImpl implements NotificationManager {
 
     protected Map<String, String> findAllSyncopeConfs() {
         Map<String, String> syncopeConfMap = new HashMap<>();
-        for (PlainAttr attr : confDAO.get().getPlainAttrs()) {
+        for (PlainAttr<?> attr : confDAO.get().getPlainAttrs()) {
             syncopeConfMap.put(attr.getSchema().getKey(), attr.getValuesAsStrings().get(0));
         }
         return syncopeConfMap;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 6408987..5c89dbb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -35,10 +35,7 @@ import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 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.AttributableUtilsFactory;
 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.Subject;
 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.Connector;
@@ -51,7 +48,12 @@ import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
@@ -88,6 +90,12 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     protected ConnObjectUtils connObjectUtils;
 
     /**
+     * Any object DAO.
+     */
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    /**
      * User DAO.
      */
     @Autowired
@@ -118,7 +126,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     protected AuditManager auditManager;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
     protected EntityFactory entityFactory;
@@ -232,40 +240,46 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         }
     }
 
-    protected Subject<?, ?, ?> getSubject(final PropagationTask task) {
-        Subject<?, ?, ?> subject = null;
+    protected Any<?, ?, ?> getAny(final PropagationTask task) {
+        Any<?, ?, ?> any = null;
 
-        if (task.getSubjectKey() != null) {
-            switch (task.getSubjectType()) {
+        if (task.getAnyKey() != null) {
+            switch (task.getAnyTypeKind()) {
                 case USER:
                     try {
-                        subject = userDAO.authFetch(task.getSubjectKey());
+                        any = userDAO.authFind(task.getAnyKey());
                     } catch (Exception e) {
-                        LOG.error("Could not read user {}", task.getSubjectKey(), e);
+                        LOG.error("Could not read user {}", task.getAnyKey(), e);
                     }
                     break;
 
                 case GROUP:
                     try {
-                        subject = groupDAO.authFetch(task.getSubjectKey());
+                        any = groupDAO.authFind(task.getAnyKey());
                     } catch (Exception e) {
-                        LOG.error("Could not read group {}", task.getSubjectKey(), e);
+                        LOG.error("Could not read group {}", task.getAnyKey(), e);
                     }
                     break;
 
-                case MEMBERSHIP:
+                case ANY_OBJECT:
                 default:
+                    try {
+                        any = anyObjectDAO.authFind(task.getAnyKey());
+                    } catch (Exception e) {
+                        LOG.error("Could not read any object {}", task.getAnyKey(), e);
+                    }
+                    break;
             }
         }
 
-        return subject;
+        return any;
     }
 
     protected void delete(final PropagationTask task, final ConnectorObject beforeObj,
             final Connector connector, final Set<String> propagationAttempted) {
 
         if (beforeObj == null) {
-            LOG.debug("{} not found on external resource: ignoring delete", task.getAccountId());
+            LOG.debug("{} not found on external resource: ignoring delete", task.getConnObjectKey());
         } else {
             /*
              * We must choose here whether to
@@ -282,7 +296,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
              * update, this user / group used to have the current resource assigned by more than one mean (for example,
              * two different memberships with the same resource).
              */
-            Subject<?, ?, ?> subject = getSubject(task);
+            Any<?, ?, ?> subject = getAny(task);
             Collection<String> resources = subject instanceof User
                     ? userDAO.findAllResourceNames((User) subject)
                     : subject instanceof Group
@@ -305,11 +319,11 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
     @Override
     public TaskExec execute(final PropagationTask task, final PropagationReporter reporter) {
-        final List<PropagationActions> actions = getPropagationActions(task.getResource());
+        List<PropagationActions> actions = getPropagationActions(task.getResource());
 
-        final Date startDate = new Date();
+        Date startDate = new Date();
 
-        final TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
         execution.setStatus(PropagationTaskExecStatus.CREATED.name());
 
         String taskExecutionMessage = null;
@@ -321,13 +335,21 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         ConnectorObject beforeObj = null;
         ConnectorObject afterObj = null;
 
+        Provision provision = null;
         Connector connector = null;
         Result result;
         try {
+            Any<?, ?, ?> any = getAny(task);
+            provision = task.getResource().getProvision(any.getType());
+            if (provision == null) {
+                throw new IllegalArgumentException("No provision found for " + any.getType() + " on " + task.
+                        getResource());
+            }
+
             connector = connFactory.getConnector(task.getResource());
 
-            // Try to read remote object (user / group) BEFORE any actual operation
-            beforeObj = getRemoteObject(task, connector, false);
+            // Try to read remote object BEFORE any actual operation
+            beforeObj = getRemoteObject(task, connector, provision, false);
 
             for (PropagationActions action : actions) {
                 action.before(task, beforeObj);
@@ -390,10 +412,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                 action.onError(task, execution, e);
             }
         } finally {
-            // Try to read remote object (user / group) AFTER any actual operation
+            // Try to read remote object AFTER any actual operation
             if (connector != null) {
                 try {
-                    afterObj = getRemoteObject(task, connector, true);
+                    afterObj = getRemoteObject(task, connector, provision, true);
                 } catch (Exception ignore) {
                     // ignore exception
                     LOG.error("Error retrieving after object", ignore);
@@ -434,7 +456,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
         notificationManager.createTasks(
                 AuditElements.EventCategoryType.PROPAGATION,
-                task.getSubjectType().name().toLowerCase(),
+                task.getAnyTypeKind().name().toLowerCase(),
                 task.getResource().getKey(),
                 task.getPropagationOperation().name().toLowerCase(),
                 result,
@@ -444,7 +466,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
 
         auditManager.audit(
                 AuditElements.EventCategoryType.PROPAGATION,
-                task.getSubjectType().name().toLowerCase(),
+                task.getAnyTypeKind().name().toLowerCase(),
                 task.getResource().getKey(),
                 task.getPropagationOperation().name().toLowerCase(),
                 result,
@@ -504,29 +526,30 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
      *
      * @param connector connector facade proxy.
      * @param task current propagation task.
+     * @param provision provision
      * @param latest 'FALSE' to retrieve object using old accountId if not null.
      * @return remote connector object.
      */
     protected ConnectorObject getRemoteObject(final PropagationTask task, final Connector connector,
-            final boolean latest) {
+            final Provision provision, final boolean latest) {
 
-        String accountId = latest || task.getOldAccountId() == null
-                ? task.getAccountId()
-                : task.getOldAccountId();
+        String connObjectKey = latest || task.getOldConnObjectKey() == null
+                ? task.getConnObjectKey()
+                : task.getOldConnObjectKey();
 
         ConnectorObject obj = null;
         try {
             obj = connector.getObject(task.getPropagationMode(),
                     task.getPropagationOperation(),
                     new ObjectClass(task.getObjectClassName()),
-                    new Uid(accountId),
-                    connector.getOperationOptions(attrUtilsFactory.getInstance(task.getSubjectType()).
-                            getMappingItems(task.getResource(), MappingPurpose.PROPAGATION)));
+                    new Uid(connObjectKey),
+                    connector.getOperationOptions(anyUtilsFactory.getInstance(task.getAnyTypeKind()).
+                            getMappingItems(provision, MappingPurpose.PROPAGATION)));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", accountId, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
 
         return obj;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
index 1e75acb..6b4760b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java
@@ -22,7 +22,7 @@ import java.util.HashSet;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -56,8 +56,8 @@ public class DBPasswordPropagationActions extends DefaultPropagationActions {
     public void before(final PropagationTask task, final ConnectorObject beforeObj) {
         super.before(task, beforeObj);
 
-        if (AttributableType.USER == task.getSubjectType()) {
-            User user = userDAO.find(task.getSubjectKey());
+        if (AnyTypeKind.USER == task.getAnyTypeKind()) {
+            User user = userDAO.find(task.getAnyKey());
 
             if (user != null && user.getPassword() != null) {
                 Attribute missing = AttributeUtil.find(
@@ -72,7 +72,7 @@ public class DBPasswordPropagationActions extends DefaultPropagationActions {
                     Attribute passwordAttribute = AttributeBuilder.buildPassword(
                             new GuardedString(user.getPassword().toCharArray()));
 
-                    Set<Attribute> attributes = new HashSet<Attribute>(task.getAttributes());
+                    Set<Attribute> attributes = new HashSet<>(task.getAttributes());
                     attributes.add(passwordAttribute);
                     attributes.remove(missing);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index c246d8f..d01b5c5 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -25,12 +25,14 @@ import java.util.Set;
 import org.apache.commons.jexl2.JexlContext;
 import org.apache.commons.jexl2.MapContext;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 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.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -51,6 +53,9 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
     protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipPropagationActions.class);
 
     @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     protected UserDAO userDAO;
 
     /**
@@ -67,23 +72,24 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
     public void before(final PropagationTask task, final ConnectorObject beforeObj) {
         super.before(task, beforeObj);
 
-        if (AttributableType.USER == task.getSubjectType() && task.getResource().getGmapping() != null) {
-            User user = userDAO.find(task.getSubjectKey());
+        Provision provision = task.getResource().getProvision(anyTypeDAO.findGroup());
+        if (AnyTypeKind.USER == task.getAnyTypeKind() && provision.getMapping() != null) {
+            User user = userDAO.find(task.getAnyKey());
             if (user != null) {
                 List<String> groupAccountLinks = new ArrayList<>();
                 for (Group group : userDAO.findAllGroups(user)) {
                     if (group.getResourceNames().contains(task.getResource().getKey())
-                            && StringUtils.isNotBlank(task.getResource().getGmapping().getAccountLink())) {
+                            && StringUtils.isNotBlank(provision.getMapping().getConnObjectLink())) {
 
                         LOG.debug("Evaluating accountLink for {}", group);
 
-                        final JexlContext jexlContext = new MapContext();
+                        JexlContext jexlContext = new MapContext();
                         JexlUtils.addFieldsToContext(group, jexlContext);
                         JexlUtils.addAttrsToContext(group.getPlainAttrs(), jexlContext);
                         JexlUtils.addDerAttrsToContext(group.getDerAttrs(), group.getPlainAttrs(), jexlContext);
 
-                        final String groupAccountLink =
-                                JexlUtils.evaluate(task.getResource().getGmapping().getAccountLink(), jexlContext);
+                        String groupAccountLink =
+                                JexlUtils.evaluate(provision.getMapping().getConnObjectLink(), jexlContext);
                         LOG.debug("AccountLink for {} is '{}'", group, groupAccountLink);
                         if (StringUtils.isNotBlank(groupAccountLink)) {
                             groupAccountLinks.add(groupAccountLink);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
index 35358af..dca9084 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java
@@ -22,7 +22,7 @@ import java.util.HashSet;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -58,8 +58,8 @@ public class LDAPPasswordPropagationActions extends DefaultPropagationActions {
     public void before(final PropagationTask task, final ConnectorObject beforeObj) {
         super.before(task, beforeObj);
 
-        if (AttributableType.USER == task.getSubjectType()) {
-            User user = userDAO.find(task.getSubjectKey());
+        if (AnyTypeKind.USER == task.getAnyTypeKind()) {
+            User user = userDAO.find(task.getAnyKey());
 
             if (user != null && user.getPassword() != null) {
                 Attribute missing = AttributeUtil.find(


[13/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
index 5c820fb..566739d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
@@ -28,8 +28,8 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 
 @Entity
 @Table(name = JPAUPlainAttrUniqueValue.TABLE)
@@ -47,7 +47,7 @@ public class JPAUPlainAttrUniqueValue extends AbstractPlainAttrValue implements
 
     @ManyToOne(optional = false)
     @JoinColumn(name = "schema_name")
-    private JPAUPlainSchema schema;
+    private JPAPlainSchema schema;
 
     @Override
     public Long getKey() {
@@ -66,14 +66,14 @@ public class JPAUPlainAttrUniqueValue extends AbstractPlainAttrValue implements
     }
 
     @Override
-    public UPlainSchema getSchema() {
+    public PlainSchema getSchema() {
         return schema;
     }
 
     @Override
     public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPAUPlainSchema.class);
-        this.schema = (JPAUPlainSchema) schema;
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java
deleted file mode 100644
index c5b8dac..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java
+++ /dev/null
@@ -1,36 +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.user;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
-
-@Entity
-@Table(name = JPAUPlainSchema.TABLE)
-@Cacheable
-public class JPAUPlainSchema extends AbstractPlainSchema implements UPlainSchema {
-
-    public static final String TABLE = "UPlainSchema";
-
-    private static final long serialVersionUID = -7272127460142463237L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java
new file mode 100644
index 0000000..d4c8bb3
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java
@@ -0,0 +1,78 @@
+/*
+ * 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.user;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+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.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
+
+@Entity
+@Table(name = JPAURelationship.TABLE)
+public class JPAURelationship extends AbstractEntity<Long> implements URelationship {
+
+    private static final long serialVersionUID = 2778494939240083204L;
+
+    public static final String TABLE = "URelationship";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @Column(name = "user_id")
+    private JPAUser leftEnd;
+
+    @ManyToOne
+    @Column(name = "anyObject_id")
+    private JPAAnyObject rightEnd;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public JPAUser getLeftEnd() {
+        return leftEnd;
+    }
+
+    @Override
+    public void setLeftEnd(final User leftEnd) {
+        checkType(leftEnd, JPAUser.class);
+        this.leftEnd = (JPAUser) leftEnd;
+    }
+
+    @Override
+    public AnyObject getRightEnd() {
+        return rightEnd;
+    }
+
+    @Override
+    public void setRightEnd(final AnyObject rightEnd) {
+        checkType(rightEnd, JPAAnyObject.class);
+        this.rightEnd = (JPAAnyObject) rightEnd;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
index c68280d..52a168e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
@@ -19,19 +19,15 @@
 package org.apache.syncope.core.persistence.jpa.entity.user;
 
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
 
 @Entity
 @Table(name = JPAUVirAttr.TABLE)
-public class JPAUVirAttr extends AbstractVirAttr implements UVirAttr {
+public class JPAUVirAttr extends AbstractVirAttr<User> implements UVirAttr {
 
     private static final long serialVersionUID = 2943450934283989741L;
 
@@ -40,28 +36,15 @@ public class JPAUVirAttr extends AbstractVirAttr implements UVirAttr {
     @ManyToOne
     private JPAUser owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAUVirSchema virSchema;
-
     @Override
     public User getOwner() {
         return owner;
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final User owner) {
         checkType(owner, JPAUser.class);
         this.owner = (JPAUser) owner;
     }
 
-    @Override
-    public UVirSchema getSchema() {
-        return virSchema;
-    }
-
-    @Override
-    public void setSchema(final VirSchema virSchema) {
-        checkType(virSchema, JPAUVirSchema.class);
-        this.virSchema = (JPAUVirSchema) virSchema;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java
deleted file mode 100644
index 307dd46..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java
+++ /dev/null
@@ -1,36 +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.user;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema;
-
-@Entity
-@Table(name = JPAUVirSchema.TABLE)
-@Cacheable
-public class JPAUVirSchema extends AbstractVirSchema implements UVirSchema {
-
-    private static final long serialVersionUID = 1089308700791426201L;
-
-    public static final String TABLE = "UVirSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
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 029c96b..f9c0c81 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
@@ -20,11 +20,8 @@ package org.apache.syncope.core.persistence.jpa.entity.user;
 
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collection;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.CascadeType;
@@ -52,29 +49,34 @@ import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.validation.entity.UserCheck;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractSubject;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
 import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.security.SecureRandomUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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.Role;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
+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.JPARole;
 
 @Entity
 @Table(name = JPAUser.TABLE)
 @Cacheable
 @UserCheck
-public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> implements User {
+public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> implements User {
 
     private static final long serialVersionUID = -3905046855521446823L;
 
@@ -96,21 +98,17 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
             @JoinColumn(name = "role_id"))
     private List<JPARole> roles;
 
-    @OneToMany(cascade = CascadeType.MERGE, mappedBy = "user")
-    @Valid
-    private List<JPAMembership> memberships;
-
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAUPlainAttr> plainAttrs;
+    private List<JPAUPlainAttr> plainAttrs = new ArrayList<>();
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAUDerAttr> derAttrs;
+    private List<JPAUDerAttr> derAttrs = new ArrayList<>();
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAUVirAttr> virAttrs;
+    private List<JPAUVirAttr> virAttrs = new ArrayList<>();
 
     private String workflowId;
 
@@ -130,7 +128,7 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     @ElementCollection
     @Column(name = "passwordHistoryValue")
     @CollectionTable(name = "SyncopeUser_passwordHistory", joinColumns =
-            @JoinColumn(name = "SyncopeUser_id", referencedColumnName = "id"))
+            @JoinColumn(name = "user_id", referencedColumnName = "id"))
     private List<String> passwordHistory;
 
     /**
@@ -174,7 +172,22 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
             inverseJoinColumns =
             @JoinColumn(name = "resource_name"))
     @Valid
-    private Set<JPAExternalResource> resources;
+    private List<JPAExternalResource> resources = new ArrayList<>();
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "user_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyTypeClass_name"))
+    private List<JPAAnyTypeClass> auxClasses = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd")
+    @Valid
+    private List<JPAURelationship> relationships = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd")
+    @Valid
+    private List<JPAUMembership> memberships = new ArrayList<>();
 
     @ManyToOne(fetch = FetchType.EAGER)
     private JPASecurityQuestion securityQuestion;
@@ -187,13 +200,9 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
 
         roles = new ArrayList<>();
         memberships = new ArrayList<>();
-        plainAttrs = new ArrayList<>();
-        derAttrs = new ArrayList<>();
-        virAttrs = new ArrayList<>();
         passwordHistory = new ArrayList<>();
         failedLogins = 0;
         suspended = getBooleanAsInteger(Boolean.FALSE);
-        resources = new HashSet<>();
     }
 
     @Override
@@ -202,18 +211,28 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     }
 
     @Override
-    protected Set<JPAExternalResource> internalGetResources() {
+    public AnyType getType() {
+        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findUser();
+    }
+
+    @Override
+    public void setType(final AnyType type) {
+        // nothing to do
+    }
+
+    @Override
+    protected List<JPAExternalResource> internalGetResources() {
         return resources;
     }
 
     @Override
-    public boolean addRole(final Role role) {
+    public boolean add(final Role role) {
         checkType(role, JPARole.class);
         return roles.contains((JPARole) role) || roles.add((JPARole) role);
     }
 
     @Override
-    public boolean removeRole(final Role role) {
+    public boolean remove(final Role role) {
         checkType(role, JPARole.class);
         return roles.remove((JPARole) role);
     }
@@ -224,45 +243,6 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     }
 
     @Override
-    public boolean addMembership(final Membership membership) {
-        checkType(membership, JPAMembership.class);
-        return memberships.contains((JPAMembership) membership) || memberships.add((JPAMembership) membership);
-    }
-
-    @Override
-    public boolean removeMembership(final Membership membership) {
-        checkType(membership, JPAMembership.class);
-        return memberships.remove((JPAMembership) membership);
-    }
-
-    @Override
-    public Membership getMembership(final Long groupKey) {
-        return CollectionUtils.find(getMemberships(), new Predicate<Membership>() {
-
-            @Override
-            public boolean evaluate(final Membership membership) {
-                return membership.getGroup() != null && groupKey.equals(membership.getGroup().getKey());
-            }
-        });
-    }
-
-    @Override
-    public List<? extends Membership> getMemberships() {
-        return memberships;
-    }
-
-    @Override
-    public Collection<Long> getStaticGroupKeys() {
-        return CollectionUtils.collect(memberships, new Transformer<Membership, Long>() {
-
-            @Override
-            public Long transform(final Membership membership) {
-                return membership.getGroup().getKey();
-            }
-        }, new HashSet<Long>());
-    }
-
-    @Override
     public String getPassword() {
         return password;
     }
@@ -309,13 +289,13 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     }
 
     @Override
-    public boolean addPlainAttr(final UPlainAttr attr) {
+    public boolean add(final UPlainAttr attr) {
         checkType(attr, JPAUPlainAttr.class);
         return plainAttrs.add((JPAUPlainAttr) attr);
     }
 
     @Override
-    public boolean removePlainAttr(final UPlainAttr attr) {
+    public boolean remove(final UPlainAttr attr) {
         checkType(attr, JPAUPlainAttr.class);
         return plainAttrs.remove((JPAUPlainAttr) attr);
     }
@@ -326,13 +306,13 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     }
 
     @Override
-    public boolean addDerAttr(final UDerAttr attr) {
+    public boolean add(final UDerAttr attr) {
         checkType(attr, JPAUDerAttr.class);
         return derAttrs.add((JPAUDerAttr) attr);
     }
 
     @Override
-    public boolean removeDerAttr(final UDerAttr attr) {
+    public boolean remove(final UDerAttr attr) {
         checkType(attr, JPAUDerAttr.class);
         return derAttrs.remove((JPAUDerAttr) attr);
     }
@@ -343,13 +323,13 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
     }
 
     @Override
-    public boolean addVirAttr(final UVirAttr attr) {
+    public boolean add(final UVirAttr attr) {
         checkType(attr, JPAUVirAttr.class);
         return virAttrs.add((JPAUVirAttr) attr);
     }
 
     @Override
-    public boolean removeVirAttr(final UVirAttr attr) {
+    public boolean remove(final UVirAttr attr) {
         checkType(attr, JPAUVirAttr.class);
         return virAttrs.remove((JPAUVirAttr) attr);
     }
@@ -528,4 +508,76 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
         this.securityAnswer = securityAnswer;
     }
 
+    @Override
+    public boolean add(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.add((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getAuxClasses() {
+        return auxClasses;
+    }
+
+    @Override
+    public boolean add(final URelationship relationship) {
+        checkType(relationship, JPAURelationship.class);
+        return this.relationships.add((JPAURelationship) relationship);
+    }
+
+    @Override
+    public boolean remove(final URelationship relationship) {
+        checkType(relationship, JPAURelationship.class);
+        return this.relationships.remove((JPAURelationship) relationship);
+    }
+
+    @Override
+    public URelationship getRelationship(final AnyObject rightEnd) {
+        return CollectionUtils.find(getRelationships(), new Predicate<URelationship>() {
+
+            @Override
+            public boolean evaluate(final URelationship relationship) {
+                return rightEnd != null && rightEnd.equals(relationship.getRightEnd());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends URelationship> getRelationships() {
+        return relationships;
+    }
+
+    @Override
+    public boolean add(final UMembership membership) {
+        checkType(membership, JPAUMembership.class);
+        return this.memberships.add((JPAUMembership) membership);
+    }
+
+    @Override
+    public boolean remove(final UMembership membership) {
+        checkType(membership, JPAUMembership.class);
+        return this.memberships.remove((JPAUMembership) membership);
+    }
+
+    @Override
+    public UMembership getMembership(final Long groupKey) {
+        return CollectionUtils.find(getMemberships(), new Predicate<UMembership>() {
+
+            @Override
+            public boolean evaluate(final UMembership membership) {
+                return groupKey != null && groupKey.equals(membership.getRightEnd().getKey());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends UMembership> getMemberships() {
+        return memberships;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
index a22359e..b7616c7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -27,12 +27,11 @@ import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.Attr;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,8 +62,7 @@ public class EntityValidationListener {
                         && !Attr.class.equals(interf)
                         && !Task.class.equals(interf)
                         && !Policy.class.equals(interf)
-                        && !Attributable.class.equals(interf)
-                        && !Subject.class.equals(interf)
+                        && !Any.class.equals(interf)
                         && Entity.class.isAssignableFrom(interf)) {
 
                     entityInt = interf;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 9fbbeab..77eea1c 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
@@ -22,13 +22,13 @@ import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.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.provisioning.api.propagation.PropagationActions;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 
 public class ExternalResourceValidator extends AbstractValidator<ExternalResourceCheck, ExternalResource> {
 
@@ -60,32 +60,29 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
         return true;
     }
 
-    private boolean isValid(final Mapping<?> mapping, final ConstraintValidatorContext context) {
+    private boolean isValid(final AnyType anyType, final Mapping mapping, final ConstraintValidatorContext context) {
         if (mapping == null) {
             return true;
         }
 
-        int accountIds = CollectionUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
+        int connObjectKeys = CollectionUtils.countMatches(mapping.getItems(), new Predicate<MappingItem>() {
 
             @Override
             public boolean evaluate(final MappingItem item) {
-                return item.isAccountid();
+                return item.isConnObjectKey();
             }
         });
-        if (accountIds != 1) {
+        if (connObjectKeys != 1) {
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping, "One and only one accountId mapping is needed")).
-                    addPropertyNode("accountId.size").addConstraintViolation();
+                    getTemplate(EntityViolationType.InvalidMapping, "Single ConnObjectKey mapping is required")).
+                    addPropertyNode("connObjectKey.size").addConstraintViolation();
             return false;
         }
 
-        final MappingItem accountId = mapping.getAccountIdItem();
-        if (mapping instanceof UMapping
-                && AttributableType.GROUP == accountId.getIntMappingType().getAttributableType()) {
-
+        MappingItem connObjectKey = mapping.getConnObjectKeyItem();
+        if (connObjectKey.getIntMappingType().getAnyTypeKind() != anyType.getKind()) {
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping,
-                            "Group attribute as accountId is not permitted")).
+                    getTemplate(EntityViolationType.InvalidMapping, "ConnObjectKey must be from the same AnyType")).
                     addPropertyNode("attributableType").addConstraintViolation();
             return false;
         }
@@ -102,7 +99,7 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
         }
         if (passwords > 1) {
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping, "One and only one password mapping is allowed")).
+                    getTemplate(EntityViolationType.InvalidMapping, "One password mapping is allowed at most")).
                     addPropertyNode("password.size").addConstraintViolation();
             isValid = false;
         }
@@ -141,6 +138,12 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             }
         }
 
-        return isValid(resource.getUmapping(), context) && isValid(resource.getGmapping(), context);
+        return CollectionUtils.matchesAll(resource.getProvisions(), new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return isValid(provision.getAnyType(), provision.getMapping(), context);
+            }
+        });
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java
index ae2e3ae..da00ebd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java
@@ -23,9 +23,6 @@ import org.apache.syncope.common.lib.types.EntityViolationType;
 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.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 
 public class PlainAttrValueValidator extends AbstractValidator<PlainAttrValueCheck, PlainAttrValue> {
 
@@ -76,16 +73,8 @@ public class PlainAttrValueValidator extends AbstractValidator<PlainAttrValueChe
                     LOG.error("Unique value schema for " + object.getClass().getSimpleName() + "[" + object.getKey()
                             + "]" + " is " + uniqueValueSchema + ", while owning attribute schema is " + attrSchema);
 
-                    EntityViolationType violationType = attrSchema instanceof UPlainSchema
-                            ? EntityViolationType.InvalidUPlainSchema
-                            : attrSchema instanceof GPlainSchema
-                                    ? EntityViolationType.InvalidGPlainSchema
-                                    : attrSchema instanceof MPlainSchema
-                                            ? EntityViolationType.InvalidMPlainSchema
-                                            : EntityViolationType.InvalidCPlainSchema;
-
                     context.disableDefaultConstraintViolation();
-                    context.buildConstraintViolationWithTemplate(getTemplate(violationType,
+                    context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidPlainSchema,
                             "Unique value schema is " + uniqueValueSchema
                             + ", while owning attribute schema is " + attrSchema)).addPropertyNode("schema").
                             addConstraintViolation();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaNameValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaNameValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaNameValidator.java
index 5084522..a9b622e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaNameValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchemaNameValidator.java
@@ -28,36 +28,23 @@ import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
+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.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 
 public class SchemaNameValidator extends AbstractValidator<SchemaNameCheck, Object> {
 
-    private static final Set<String> UNALLOWED_USCHEMA_NAMES = new HashSet<>();
-
-    private static final Set<String> UNALLOWED_MSCHEMA_NAMES = new HashSet<>();
-
-    private static final Set<String> UNALLOWED_RSCHEMA_NAMES = new HashSet<>();
-
-    private static final Set<String> UNALLOWED_CSCHEMA_NAMES = new HashSet<>();
+    private static final Set<String> UNALLOWED_SCHEMA_NAMES = new HashSet<>();
 
     static {
-        initUnallowedSchemaNames(JPAUser.class, UNALLOWED_USCHEMA_NAMES);
-        initUnallowedSchemaNames(JPAMembership.class, UNALLOWED_MSCHEMA_NAMES);
-        initUnallowedSchemaNames(JPAGroup.class, UNALLOWED_RSCHEMA_NAMES);
-        initUnallowedSchemaNames(JPAConf.class, UNALLOWED_CSCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAAnyObject.class, UNALLOWED_SCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAGroup.class, UNALLOWED_SCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAUser.class, UNALLOWED_SCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAConf.class, UNALLOWED_SCHEMA_NAMES);
     }
 
     private static void initUnallowedSchemaNames(final Class<?> entityClass, final Set<String> names) {
@@ -78,39 +65,14 @@ public class SchemaNameValidator extends AbstractValidator<SchemaNameCheck, Obje
 
     @Override
     public boolean isValid(final Object object, final ConstraintValidatorContext context) {
-        final String schemaName;
-        final Set<String> unallowedNames;
-
-        if (object instanceof UPlainSchema) {
-            schemaName = ((UPlainSchema) object).getKey();
-            unallowedNames = UNALLOWED_USCHEMA_NAMES;
-        } else if (object instanceof UDerSchema) {
-            schemaName = ((UDerSchema) object).getKey();
-            unallowedNames = UNALLOWED_USCHEMA_NAMES;
-        } else if (object instanceof UVirSchema) {
-            schemaName = ((UVirSchema) object).getKey();
-            unallowedNames = UNALLOWED_USCHEMA_NAMES;
-        } else if (object instanceof MPlainSchema) {
-            schemaName = ((MPlainSchema) object).getKey();
-            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
-        } else if (object instanceof MDerSchema) {
-            schemaName = ((MDerSchema) object).getKey();
-            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
-        } else if (object instanceof MVirSchema) {
-            schemaName = ((MVirSchema) object).getKey();
-            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
-        } else if (object instanceof GPlainSchema) {
-            schemaName = ((GPlainSchema) object).getKey();
-            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
-        } else if (object instanceof GDerSchema) {
-            schemaName = ((GDerSchema) object).getKey();
-            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
-        } else if (object instanceof GVirSchema) {
-            schemaName = ((GVirSchema) object).getKey();
-            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
-        } else if (object instanceof CPlainSchema) {
-            schemaName = ((CPlainSchema) object).getKey();
-            unallowedNames = UNALLOWED_CSCHEMA_NAMES;
+        String schemaName;
+        Set<String> unallowedNames = UNALLOWED_SCHEMA_NAMES;
+        if (object instanceof PlainSchema) {
+            schemaName = ((PlainSchema) object).getKey();
+        } else if (object instanceof DerSchema) {
+            schemaName = ((DerSchema) object).getKey();
+        } else if (object instanceof VirSchema) {
+            schemaName = ((VirSchema) object).getKey();
         } else {
             schemaName = null;
             unallowedNames = Collections.emptySet();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
index 19fc7cf..e142de3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
@@ -26,7 +26,7 @@ import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.user.User;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index 5562674..9d300d0 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -36,8 +36,8 @@ under the License.
   
   <table-generator name="SEQ_UPlainAttrValue" pk-column-value="SEQ_UPlainAttrValue" initial-value="100"/>
   <table-generator name="SEQ_GPlainAttrValue" pk-column-value="SEQ_GPlainAttrValue" initial-value="100"/>
-  <table-generator name="SEQ_MAttrPlainValue" pk-column-value="SEQ_MAttrPlainValue" initial-value="100"/>
-  <table-generator name="SEQ_CAttrPlainValue" pk-column-value="SEQ_CAttrPlainValue" initial-value="100"/>
+  <table-generator name="SEQ_APlainAttrValue" pk-column-value="SEQ_APlainAttrValue" initial-value="100"/>
+  <table-generator name="SEQ_CPlainAttrValue" pk-column-value="SEQ_CPlainAttrValue" initial-value="100"/>
 
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARealm">
     <attributes>
@@ -47,7 +47,25 @@ under the License.
       </id>
     </attributes>
   </entity>
-
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyObject" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyObject" pk-column-value="SEQ_AnyObject" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ARelationship" strategy="TABLE"/>
+        <table-generator name="SEQ_ARelationship" pk-column-value="SEQ_ARelationship" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole">
     <attributes>
       <id name="id">
@@ -57,7 +75,7 @@ under the License.
     </attributes>
   </entity>
   
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_DynRoleMembership" strategy="TABLE"/>
@@ -74,63 +92,65 @@ under the License.
       </id>
     </attributes>
   </entity>
-
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup">
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_Group" strategy="TABLE"/>
-        <table-generator name="SEQ_Group" pk-column-value="SEQ_Group" initial-value="100"/>
+        <generated-value generator="SEQ_URelationship" strategy="TABLE"/>
+        <table-generator name="SEQ_URelationship" pk-column-value="SEQ_URelationship" initial-value="100"/>
       </id>
     </attributes>
   </entity>
   
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_DynGroupMembership" strategy="TABLE"/>
-        <table-generator name="SEQ_DynGroupMembership" pk-column-value="SEQ_DynGroupMembership" initial-value="100"/>
+        <generated-value generator="SEQ_Group" strategy="TABLE"/>
+        <table-generator name="SEQ_Group" pk-column-value="SEQ_Group" initial-value="100"/>
       </id>
     </attributes>
   </entity>
-  
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_Membership" strategy="TABLE"/>
-        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="100"/>
+        <generated-value generator="SEQ_ADynGroupMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_ADynGroupMembership" pk-column-value="SEQ_ADynGroupMembership" initial-value="100"/>
       </id>
     </attributes>
   </entity>
-
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUMapping">
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_UMapping" strategy="TABLE"/>
-        <table-generator name="SEQ_UMapping" pk-column-value="SEQ_UMapping" initial-value="100"/>
+        <generated-value generator="SEQ_UDynGroupMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_UDynGroupMembership" pk-column-value="SEQ_UDynGroupMembership" initial-value="100"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGMapping">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.resource.JPAProvision">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_GMapping" strategy="TABLE"/>
-        <table-generator name="SEQ_GMapping" pk-column-value="SEQ_GMapping" initial-value="100"/>
+        <generated-value generator="SEQ_Provision" strategy="TABLE"/>
+        <table-generator name="SEQ_Provision" pk-column-value="SEQ_Provision" initial-value="100"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem">
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_UMappingItem" strategy="TABLE"/>
-        <table-generator name="SEQ_UMappingItem" pk-column-value="SEQ_UMappingItem" initial-value="1000"/>
+        <generated-value generator="SEQ_Mapping" strategy="TABLE"/>
+        <table-generator name="SEQ_Mapping" pk-column-value="SEQ_Mapping" initial-value="100"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_GMappingItem" strategy="TABLE"/>
-        <table-generator name="SEQ_GMappingItem" pk-column-value="SEQ_GMappingItem" initial-value="1000"/>
+        <generated-value generator="SEQ_MappingItem" strategy="TABLE"/>
+        <table-generator name="SEQ_MappingItem" pk-column-value="SEQ_MappingItem" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
@@ -144,6 +164,14 @@ under the License.
     </attributes>
   </entity>
 
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_APlainAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_APlainAttr" pk-column-value="SEQ_APlainAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr">
     <attributes>
       <id name="id">
@@ -160,30 +188,6 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrTemplate">
-    <attributes>
-      <id name="id">
-        <generated-value generator="SEQ_GPlainAttrTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_GPlainAttrTemplate" pk-column-value="SEQ_GPlainAttrTemplate" initial-value="1000"/>
-      </id>
-    </attributes>
-  </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr">
-    <attributes>
-      <id name="id">
-        <generated-value generator="SEQ_MPlainAttr" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttr" pk-column-value="SEQ_MPlainAttr" initial-value="1000"/>
-      </id>
-    </attributes>
-  </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate">
-    <attributes>
-      <id name="id">
-        <generated-value generator="SEQ_MPlainAttrTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttrTemplate" pk-column-value="SEQ_MPlainAttrTemplate" initial-value="1000"/>
-      </id>
-    </attributes>
-  </entity>
   <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr">
     <attributes>
       <id name="id">
@@ -192,15 +196,15 @@ under the License.
       </id>
     </attributes>
   </entity>
-    
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -225,18 +229,18 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
-  </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue">
+  </entity>    
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_GPlainAttrValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -261,18 +265,18 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_GPlainAttrValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_GPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -297,14 +301,14 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_GPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
   <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
@@ -333,7 +337,25 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyTemplate" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyTemplate" pk-column-value="SEQ_AnyTemplate" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyFilter">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyFilter" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyFilter" pk-column-value="SEQ_AnyFilter" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
@@ -388,6 +410,15 @@ under the License.
       </id>
     </attributes>
   </entity>
+  
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.JPAAnyAbout">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AnyAbout" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyAbout" pk-column-value="SEQ_AnyAbout" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPANotification">
     <attributes>
       <id name="id">
@@ -396,6 +427,7 @@ under the License.
       </id>
     </attributes>
   </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion">
     <attributes>
       <id name="id">

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/content.xml b/core/persistence-jpa/src/main/resources/content.xml
index 0f4ab83..20b2ebc 100644
--- a/core/persistence-jpa/src/main/resources/content.xml
+++ b/core/persistence-jpa/src/main/resources/content.xml
@@ -24,8 +24,8 @@ under the License.
                creator="admin" lastModifier="admin"
                creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
 
-  <CPlainSchema name="password.cipher.algorithm" type="String"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
   <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
 
@@ -33,71 +33,70 @@ under the License.
   + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
   + provided as empty string: NotificationJob disabled
   + provided as non-empty string: NotificationJob runs according to the given value -->
-  <CPlainSchema name="notificationjob.cronExpression" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
   <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
 
-  <CPlainSchema name="notification.maxRetries" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
   <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
 
-  <CPlainSchema name="token.length" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
   <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
 
-  <CPlainSchema name="token.expireTime" type="Long"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
   <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
 
-  <CPlainSchema name="selfRegistration.allowed" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
   <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
 
-  <CPlainSchema name="passwordReset.allowed" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
   <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
 
-  <CPlainSchema name="passwordReset.securityQuestion" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
   <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
 
-  <CPlainSchema name="authentication.statuses" type="String"
-                mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
   <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
   <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
 
   <!-- Save user login date upon successful authentication -->
-  <CPlainSchema name="log.lastlogindate" type="Boolean"
-                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
   <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
 
   <!-- For usage with admin console -->
-  <CPlainSchema name="admin.user.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.user.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="admin.group.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.group.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="admin.membership.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainSchema name="self.membership.layout" type="String"
-                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
         
-  <!-- User pre-defined schemas -->
-  <UPlainSchema name="email" type="String"
-                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="email" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
   
   <!-- Password reset notifications -->
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/resources/indexes.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/indexes.xml b/core/persistence-jpa/src/main/resources/indexes.xml
index abd3a76..ae57529 100644
--- a/core/persistence-jpa/src/main/resources/indexes.xml
+++ b/core/persistence-jpa/src/main/resources/indexes.xml
@@ -26,15 +26,20 @@ under the License.
   <entry key="UPlainAttrValue_longvalueIndex">CREATE INDEX UAttrValue_longvalueIndex ON UPlainAttrValue(longvalue)</entry>
   <entry key="UPlainAttrValue_doublevalueIndex">CREATE INDEX UAttrValue_doublevalueIndex ON UPlainAttrValue(doublevalue)</entry>
   <entry key="UPlainAttrValue_booleanvalueIndex">CREATE INDEX UAttrValue_booleanvalueIndex ON UPlainAttrValue(booleanvalue)</entry>
-  <entry key="MPlainAttrValue_stringvalueIndex">CREATE INDEX MAttrValue_stringvalueIndex ON MPlainAttrValue(stringvalue)</entry>
-  <entry key="MPlainAttrValue_datevalueIndex">CREATE INDEX MAttrValue_datevalueIndex ON MPlainAttrValue(datevalue)</entry>
-  <entry key="MPlainAttrValue_longvalueIndex">CREATE INDEX MAttrValue_longvalueIndex ON MPlainAttrValue(longvalue)</entry>
-  <entry key="MPlainAttrValue_doublevalueIndex">CREATE INDEX MAttrValue_doublevalueIndex ON MPlainAttrValue(doublevalue)</entry>
-  <entry key="MPlainAttrValue_booleanvalueIndex">CREATE INDEX MAttrValue_booleanvalueIndex ON MPlainAttrValue(booleanvalue)</entry>
+  <entry key="APlainAttrValue_stringvalueIndex">CREATE INDEX AAttrValue_stringvalueIndex ON APlainAttrValue(stringvalue)</entry>
+  <entry key="APlainAttrValue_datevalueIndex">CREATE INDEX AAttrValue_datevalueIndex ON APlainAttrValue(datevalue)</entry>
+  <entry key="APlainAttrValue_longvalueIndex">CREATE INDEX AAttrValue_longvalueIndex ON APlainAttrValue(longvalue)</entry>
+  <entry key="APlainAttrValue_doublevalueIndex">CREATE INDEX AAttrValue_doublevalueIndex ON APlainAttrValue(doublevalue)</entry>
+  <entry key="APlainAttrValue_booleanvalueIndex">CREATE INDEX AAttrValue_booleanvalueIndex ON APlainAttrValue(booleanvalue)</entry>
   <entry key="GPlainAttrValue_stringvalueIndex">CREATE INDEX GAttrValue_stringvalueIndex ON GPlainAttrValue(stringvalue)</entry>
   <entry key="GPlainAttrValue_datevalueIndex">CREATE INDEX GAttrValue_datevalueIndex ON GPlainAttrValue(datevalue)</entry>
   <entry key="GPlainAttrValue_longvalueIndex">CREATE INDEX GAttrValue_longvalueIndex ON GPlainAttrValue(longvalue)</entry>
   <entry key="GPlainAttrValue_doublevalueIndex">CREATE INDEX GAttrValue_doublevalueIndex ON GPlainAttrValue(doublevalue)</entry>
   <entry key="GPlainAttrValue_booleanvalueIndex">CREATE INDEX GAttrValue_booleanvalueIndex ON GPlainAttrValue(booleanvalue)</entry>
+  <entry key="CPlainAttrValue_stringvalueIndex">CREATE INDEX CAttrValue_stringvalueIndex ON CPlainAttrValue(stringvalue)</entry>
+  <entry key="CPlainAttrValue_datevalueIndex">CREATE INDEX CAttrValue_datevalueIndex ON CPlainAttrValue(datevalue)</entry>
+  <entry key="CPlainAttrValue_longvalueIndex">CREATE INDEX CAttrValue_longvalueIndex ON CPlainAttrValue(longvalue)</entry>
+  <entry key="CPlainAttrValue_doublevalueIndex">CREATE INDEX CAttrValue_doublevalueIndex ON CPlainAttrValue(doublevalue)</entry>
+  <entry key="CPlainAttrValue_booleanvalueIndex">CREATE INDEX CAttrValue_booleanvalueIndex ON CPlainAttrValue(booleanvalue)</entry>
   <entry key="Task_executedIndex">CREATE INDEX Task_executedIndex ON Task(executed)</entry>
 </properties>

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/resources/views.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/views.xml b/core/persistence-jpa/src/main/resources/views.xml
index f7bce20..a00b786 100644
--- a/core/persistence-jpa/src/main/resources/views.xml
+++ b/core/persistence-jpa/src/main/resources/views.xml
@@ -20,15 +20,17 @@ under the License.
 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 <properties>
   <comment>Views</comment>
+  
+  <!-- user -->
   <entry key="user_search">
     CREATE VIEW user_search AS
  
-    SELECT u.id as subject_id, u.* FROM SyncopeUser u
+    SELECT u.id as any_id, u.* FROM SyncopeUser u
   </entry>
   <entry key="user_search_unique_attr">
     CREATE VIEW user_search_unique_attr AS
 
-    SELECT ua.owner_id AS subject_id,
+    SELECT ua.owner_id AS any_id,
     ua.schema_name AS schema_name,
     uav.booleanvalue AS booleanvalue,
     uav.datevalue AS datevalue,
@@ -41,7 +43,7 @@ under the License.
   <entry key="user_search_attr">
     CREATE VIEW user_search_attr AS
 
-    SELECT ua.owner_id AS subject_id,
+    SELECT ua.owner_id AS any_id,
     ua.schema_name AS schema_name,
     uav.booleanvalue AS booleanvalue,
     uav.datevalue AS datevalue,
@@ -54,109 +56,194 @@ under the License.
   <entry key="user_search_null_attr">
     CREATE VIEW user_search_null_attr AS
 
-    SELECT u.id AS subject_id,
-    UPlainSchema.name AS schema_name,
+    SELECT u.id AS any_id,
+    PlainSchema.name AS schema_name,
     NULL AS booleanvalue,
     NULL AS datevalue,
     NULL AS doublevalue,
     NULL AS longvalue,
     NULL AS stringvalue
-    FROM SyncopeUser u CROSS JOIN UPlainSchema
-    LEFT OUTER JOIN UPlainAttr ua ON (UPlainSchema.name = ua.schema_name AND ua.owner_id = u.id)
+    FROM SyncopeUser u CROSS JOIN PlainSchema
+    LEFT OUTER JOIN UPlainAttr ua ON (PlainSchema.name = ua.schema_name AND ua.owner_id = u.id)
     WHERE ua.id IS NULL
   </entry>
-  <entry key="user_search_membership">
-    CREATE VIEW user_search_membership AS
+  <entry key="user_search_urelationship">
+    CREATE VIEW user_search_urelationship AS
 
-    SELECT m.user_id AS subject_id, g.id AS group_id, g.name AS group_name
-    FROM Membership m, SyncopeGroup g
+    SELECT m.user_id AS any_id, m.anyObject_id AS anyObject_id
+    FROM URelationship m
+  </entry>
+  <entry key="user_search_umembership">
+    CREATE VIEW user_search_umembership AS
+
+    SELECT m.user_id AS any_id, g.id AS group_id, g.name AS group_name
+    FROM UMembership m, SyncopeGroup g
     WHERE m.group_id = g.id
   </entry>
-  <entry key="user_search_dyngroupmembership">
-    CREATE VIEW user_search_dyngroupmembership AS
+  <entry key="user_search_udyngroupmembership">
+    CREATE VIEW user_search_udyngroupmembership AS
 
-    SELECT ds.user_id AS subject_id, d.group_id AS group_id
-    FROM DynGroupMembership d, DynGroupMembership_SyncopeUser ds
-    WHERE d.id = ds.dynGroupMembership_id
+    SELECT ds.user_id AS any_id, d.group_id AS group_id
+    FROM UDynGroupMembership d, UDynGroupMembership_SyncopeUser ds
+    WHERE d.id = ds.uDynGroupMembership_id
   </entry>
   <entry key="user_search_role">
     CREATE VIEW user_search_role AS
 
-    SELECT ss.user_id AS subject_id, ss.role_id AS role_id
+    SELECT ss.user_id AS any_id, ss.role_id AS role_id
     FROM SyncopeUser_SyncopeRole ss
   </entry>
   <entry key="user_search_dynrolemembership">
     CREATE VIEW user_search_dynrolemembership AS
 
-    SELECT ds.user_id AS subject_id, d.role_id AS role_id
+    SELECT ds.user_id AS any_id, d.role_id AS role_id
     FROM DynRoleMembership d, DynRoleMembership_SyncopeUser ds
     WHERE d.id = ds.dynRoleMembership_id
   </entry>
   <entry key="user_search_resource">
     CREATE VIEW user_search_resource AS
 
-    SELECT st.user_id AS subject_id, st.resource_name AS resource_name
+    SELECT st.user_id AS any_id, st.resource_name AS resource_name
     FROM SyncopeUser_ExternalResource st
   </entry>
   <entry key="user_search_group_resource">
     CREATE VIEW user_search_group_resource AS
 
-    SELECT m.user_id AS subject_id, st.resource_name AS resource_name
-    FROM Membership m, SyncopeGroup r, SyncopeGroup_ExternalResource st
+    SELECT m.user_id AS any_id, st.resource_name AS resource_name
+    FROM UMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st
     WHERE m.group_id = r.id AND st.group_id = r.id
   </entry>
+
+  <!-- anyObject -->
+  <entry key="anyObject_search">
+    CREATE VIEW anyObject_search AS
+ 
+    SELECT a.id as any_id, a.* FROM AnyObject a
+  </entry>
+  <entry key="anyObject_search_unique_attr">
+    CREATE VIEW anyObject_search_unique_attr AS
+
+    SELECT ua.owner_id AS any_id,
+    ua.schema_name AS schema_name,
+    uav.booleanvalue AS booleanvalue,
+    uav.datevalue AS datevalue,
+    uav.doublevalue AS doublevalue,
+    uav.longvalue AS longvalue,
+    uav.stringvalue AS stringvalue
+    FROM APlainAttrUniqueValue uav, APlainAttr ua
+    WHERE uav.attribute_id = ua.id
+  </entry>
+  <entry key="anyObject_search_attr">
+    CREATE VIEW anyObject_search_attr AS
+
+    SELECT ua.owner_id AS any_id,
+    ua.schema_name AS schema_name,
+    uav.booleanvalue AS booleanvalue,
+    uav.datevalue AS datevalue,
+    uav.doublevalue AS doublevalue,
+    uav.longvalue AS longvalue,
+    uav.stringvalue AS stringvalue
+    FROM APlainAttrValue uav, APlainAttr ua
+    WHERE uav.attribute_id = ua.id
+  </entry>
+  <entry key="anyObject_search_null_attr">
+    CREATE VIEW anyObject_search_null_attr AS
+
+    SELECT u.id AS any_id,
+    PlainSchema.name AS schema_name,
+    NULL AS booleanvalue,
+    NULL AS datevalue,
+    NULL AS doublevalue,
+    NULL AS longvalue,
+    NULL AS stringvalue
+    FROM AnyObject u CROSS JOIN PlainSchema
+    LEFT OUTER JOIN APlainAttr ua ON (PlainSchema.name = ua.schema_name AND ua.owner_id = u.id)
+    WHERE ua.id IS NULL
+  </entry>
+  <entry key="anyObject_search_arelationship">
+    CREATE VIEW anyObject_search_arelationship AS
+
+    SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_anyObject_id
+    FROM ARelationship m
+  </entry>
+  <entry key="anyObject_search_amembership">
+    CREATE VIEW anyObject_search_amembership AS
+
+    SELECT m.anyObject_id AS any_id, g.id AS group_id, g.name AS group_name
+    FROM AMembership m, SyncopeGroup g
+    WHERE m.group_id = g.id
+  </entry>
+  <entry key="anyObject_search_adyngroupmembership">
+    CREATE VIEW anyObject_search_adyngroupmembership AS
+
+    SELECT ds.anyObject_id AS any_id, d.group_id AS group_id
+    FROM ADynGroupMembership d, ADynGroupMembership_AnyObject ds
+    WHERE d.id = ds.aDynGroupMembership_id
+  </entry>
+  <entry key="anyObject_search_resource">
+    CREATE VIEW anyObject_search_resource AS
+
+    SELECT st.anyObject_id AS any_id, st.resource_name AS resource_name
+    FROM AnyObject_ExternalResource st
+  </entry>
+  <entry key="anyObject_search_group_resource">
+    CREATE VIEW anyObject_search_group_resource AS
+
+    SELECT m.anyObject_id AS any_id, st.resource_name AS resource_name
+    FROM AMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st
+    WHERE m.group_id = r.id AND st.group_id = r.id
+  </entry>
+
+  <!-- group -->
   <entry key="group_search">
     CREATE VIEW group_search AS
  
-    SELECT r.id as subject_id, r.* FROM SyncopeGroup r
+    SELECT r.id as any_id, r.* FROM SyncopeGroup r
   </entry>
   <entry key="group_search_unique_attr">
     CREATE VIEW group_search_unique_attr AS
 
-    SELECT ra.owner_id AS subject_id,
-    rat.schema_name AS schema_name,
-    rav.booleanvalue AS booleanvalue,
-    rav.datevalue AS datevalue,
-    rav.doublevalue AS doublevalue,
-    rav.longvalue AS longvalue,
-    rav.stringvalue AS stringvalue
-    FROM GPlainAttrUniqueValue rav, GPlainAttr ra, GPlainAttrTemplate rat
-    WHERE rav.attribute_id = ra.id
-    AND ra.template_id = rat.id
+    SELECT ua.owner_id AS any_id,
+    ua.schema_name AS schema_name,
+    uav.booleanvalue AS booleanvalue,
+    uav.datevalue AS datevalue,
+    uav.doublevalue AS doublevalue,
+    uav.longvalue AS longvalue,
+    uav.stringvalue AS stringvalue
+    FROM GPlainAttrUniqueValue uav, GPlainAttr ua
+    WHERE uav.attribute_id = ua.id
   </entry>
   <entry key="group_search_attr">
     CREATE VIEW group_search_attr AS
 
-    SELECT ra.owner_id AS subject_id,
-    rat.schema_name AS schema_name,
-    rav.booleanvalue AS booleanvalue,
-    rav.datevalue AS datevalue,
-    rav.doublevalue AS doublevalue,
-    rav.longvalue AS longvalue,
-    rav.stringvalue AS stringvalue
-    FROM GPlainAttrValue rav, GPlainAttr ra, GPlainAttrTemplate rat
-    WHERE rav.attribute_id = ra.id
-    AND ra.template_id = rat.id
+    SELECT ua.owner_id AS any_id,
+    ua.schema_name AS schema_name,
+    uav.booleanvalue AS booleanvalue,
+    uav.datevalue AS datevalue,
+    uav.doublevalue AS doublevalue,
+    uav.longvalue AS longvalue,
+    uav.stringvalue AS stringvalue
+    FROM GPlainAttrValue uav, GPlainAttr ua
+    WHERE uav.attribute_id = ua.id
   </entry>
   <entry key="group_search_null_attr">
     CREATE VIEW group_search_null_attr AS
 
-    SELECT r.id AS subject_id,
-    GPlainSchema.name AS schema_name,
+    SELECT u.id AS any_id,
+    PlainSchema.name AS schema_name,
     NULL AS booleanvalue,
     NULL AS datevalue,
     NULL AS doublevalue,
     NULL AS longvalue,
     NULL AS stringvalue
-    FROM SyncopeGroup r CROSS JOIN GPlainSchema
-    LEFT OUTER JOIN GPlainAttr ra ON (ra.owner_id = r.id)
-    LEFT OUTER JOIN GPlainAttrTemplate rat ON (GPlainSchema.name = rat.schema_name AND ra.template_id = rat.id)
-    WHERE ra.id IS NULL
+    FROM SyncopeGroup u CROSS JOIN PlainSchema
+    LEFT OUTER JOIN GPlainAttr ua ON (PlainSchema.name = ua.schema_name AND ua.owner_id = u.id)
+    WHERE ua.id IS NULL
   </entry>
   <entry key="group_search_resource">
     CREATE VIEW group_search_resource AS
 
-    SELECT st.group_id AS subject_id, st.resource_name AS resource_name
+    SELECT st.group_id AS any_id, st.resource_name AS resource_name
     FROM SyncopeGroup_ExternalResource st
   </entry>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
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 668c868..a3b6701 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
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +33,6 @@ public abstract class AbstractTest {
     protected EntityFactory entityFactory;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
index fad038e..91618d2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
@@ -22,7 +22,7 @@ import java.util.Set;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.springframework.stereotype.Component;
 


[19/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 4e6b985..22ce79e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -18,101 +18,72 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.persistence.NoResultException;
-import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.misc.RealmUtils;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+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.user.UMembership;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 @Repository
-public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAttr> implements GroupDAO {
+public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Autowired
-    private VirAttrDAO virAttrDAO;
+    private AnyObjectDAO anyObjectDAO;
 
     @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
+    private UserDAO userDAO;
 
     @Override
-    protected Subject<GPlainAttr, GDerAttr, GVirAttr> findInternal(final Long key) {
-        return find(key);
+    protected AnyUtils init() {
+        return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.GROUP);
     }
 
     @Override
-    public Group find(final Long key) {
-        TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.id = :id", Group.class);
-        query.setParameter("id", key);
+    protected void securityChecks(final Group group) {
+        Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_READ);
+        boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {
 
-        Group result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No group found with id {}", key, e);
+            @Override
+            public boolean evaluate(final String realm) {
+                return group.getRealm().getFullPath().startsWith(realm)
+                        || realm.equals(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
+            }
+        });
+        if (authRealms == null || authRealms.isEmpty() || !authorized) {
+            throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
         }
-
-        return result;
     }
 
     @Override
@@ -168,74 +139,22 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt
         return query.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public List<Group> findByAttrValue(final String schemaName, final GPlainAttrValue attrValue) {
-        return (List<Group>) findByAttrValue(
-                schemaName, attrValue, attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Group findByAttrUniqueValue(final String schemaName, final GPlainAttrValue attrUniqueValue) {
-        return (Group) findByAttrUniqueValue(
-                schemaName, attrUniqueValue, attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<Group> findByDerAttrValue(final String schemaName, final String value) {
-        return (List<Group>) findByDerAttrValue(
-                schemaName, value, attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<Group> findByResource(final ExternalResource resource) {
-        return (List<Group>) findByResource(resource, attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @Override
-    public final List<Group> findAll(final Set<String> adminRealms, final int page, final int itemsPerPage) {
-        return findAll(adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList());
-    }
-
-    @Override
-    public List<Group> findAll(final Set<String> adminRealms,
-            final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
-
-        return searchDAO.search(adminRealms, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.GROUP);
-    }
-
-    @Override
-    public final int count(final Set<String> adminRealms) {
-        return searchDAO.count(adminRealms, getAllMatchingCond(), SubjectType.GROUP);
-    }
-
-    @Override
-    public List<Membership> findMemberships(final Group group) {
-        TypedQuery<Membership> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e WHERE e.group=:group", Membership.class);
+    public List<AMembership> findAMemberships(final Group group) {
+        TypedQuery<AMembership> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAAMembership.class.getSimpleName()
+                + " e WHERE e.rightEnd=:group", AMembership.class);
         query.setParameter("group", group);
 
         return query.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
-    private List<Long> unmatched(final Long groupId,
-            final Class<?> attrClass, final Class<? extends AttrTemplate<?>> attrTemplateClass) {
-
-        final Query query = entityManager.createNativeQuery(new StringBuilder().
-                append("SELECT ma.id ").
-                append("FROM ").append(JPAMembership.TABLE).append(" m, ").
-                append(attrClass.getSimpleName()).append(" ma ").
-                append("WHERE m.group_id = ?1 ").
-                append("AND ma.owner_id = m.id ").
-                append("AND ma.template_id NOT IN (").
-                append("SELECT id ").
-                append("FROM ").append(attrTemplateClass.getSimpleName()).append(' ').
-                append("WHERE owner_id = ?1)").toString());
-        query.setParameter(1, groupId);
+    @Override
+    public List<UMembership> findUMemberships(final Group group) {
+        TypedQuery<UMembership> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAUMembership.class.getSimpleName()
+                + " e WHERE e.rightEnd=:group", UMembership.class);
+        query.setParameter("group", group);
 
         return query.getResultList();
     }
@@ -243,108 +162,39 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt
     @Override
     public Group save(final Group group) {
         // refresh dynaminc memberships
-        if (group.getDynMembership() != null) {
-            List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                    SearchCondConverter.convert(group.getDynMembership().getFIQLCond()), SubjectType.USER);
-
-            group.getDynMembership().getUsers().clear();
-            for (User user : matchingUsers) {
-                group.getDynMembership().addUser(user);
-            }
-        }
+        if (group.getADynMembership() != null) {
+            List<AnyObject> matching = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                    SearchCondConverter.convert(group.getADynMembership().getFIQLCond()), AnyTypeKind.ANY_OBJECT);
 
-        // remove plain attributes without a valid template
-        List<GPlainAttr> rToBeDeleted = new ArrayList<>();
-        for (final PlainAttr attr : group.getPlainAttrs()) {
-            boolean found = CollectionUtils.exists(group.getAttrTemplates(GPlainAttrTemplate.class),
-                    new Predicate<GPlainAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final GPlainAttrTemplate template) {
-                            return template.getSchema().equals(attr.getSchema());
-                        }
-                    });
-            if (!found) {
-                rToBeDeleted.add((GPlainAttr) attr);
+            group.getADynMembership().getMembers().clear();
+            for (AnyObject anyObject : matching) {
+                group.getADynMembership().add(anyObject);
             }
         }
-        for (GPlainAttr attr : rToBeDeleted) {
-            LOG.debug("Removing {} from {} because no template is available for it", attr, group);
-            group.removePlainAttr(attr);
-        }
+        if (group.getUDynMembership() != null) {
+            List<User> matching = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                    SearchCondConverter.convert(group.getUDynMembership().getFIQLCond()), AnyTypeKind.USER);
 
-        // remove derived attributes without a valid template
-        List<GDerAttr> rDerToBeDeleted = new ArrayList<>();
-        for (final DerAttr attr : group.getDerAttrs()) {
-            boolean found = CollectionUtils.exists(group.getAttrTemplates(GDerAttrTemplate.class),
-                    new Predicate<GDerAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final GDerAttrTemplate template) {
-                            return template.getSchema().equals(attr.getSchema());
-                        }
-                    });
-            if (!found) {
-                rDerToBeDeleted.add((GDerAttr) attr);
+            group.getUDynMembership().getMembers().clear();
+            for (User user : matching) {
+                group.getUDynMembership().add(user);
             }
         }
-        for (GDerAttr attr : rDerToBeDeleted) {
-            LOG.debug("Removing {} from {} because no template is available for it", attr, group);
-            group.removeDerAttr(attr);
-        }
 
-        // remove virtual attributes without a valid template
-        List<GVirAttr> rVirToBeDeleted = new ArrayList<>();
-        for (final VirAttr attr : group.getVirAttrs()) {
-            boolean found = CollectionUtils.exists(group.getAttrTemplates(GVirAttrTemplate.class),
-                    new Predicate<GVirAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final GVirAttrTemplate template) {
-                            return template.getSchema().equals(attr.getSchema());
-                        }
-                    });
-            if (!found) {
-                LOG.debug("Removing {} from {} because no template is available for it", attr, group);
-                rVirToBeDeleted.add((GVirAttr) attr);
-            }
-        }
-        for (GVirAttr attr : rVirToBeDeleted) {
-            group.removeVirAttr(attr);
-        }
-
-        Group merged = entityManager.merge(group);
-
-        // Now the same process for any exising membership of the group being saved
-        if (group.getKey() != null) {
-            for (Long key : unmatched(group.getKey(), MPlainAttr.class, MPlainAttrTemplate.class)) {
-                LOG.debug("Removing MAttr[{}] because no template is available for it in {}", key, group);
-                plainAttrDAO.delete(key, MPlainAttr.class);
-            }
-            for (Long id : unmatched(group.getKey(), MDerAttr.class, MDerAttrTemplate.class)) {
-                LOG.debug("Removing MDerAttr[{}] because no template is available for it in {}", id, group);
-                derAttrDAO.delete(id, MDerAttr.class);
-            }
-            for (Long id : unmatched(group.getKey(), MVirAttr.class, MVirAttrTemplate.class)) {
-                LOG.debug("Removing MVirAttr[{}] because no template is available for it in {}", id, group);
-                virAttrDAO.delete(id, MVirAttr.class);
-            }
-        }
-
-        merged = entityManager.merge(merged);
-        for (VirAttr attr : merged.getVirAttrs()) {
-            attr.getValues().clear();
-            attr.getValues().addAll(group.getVirAttr(attr.getSchema().getKey()).getValues());
-        }
-
-        return merged;
+        return super.save(group);
     }
 
     @Override
     public void delete(final Group group) {
-        for (Membership membership : findMemberships(group)) {
-            membership.getUser().removeMembership(membership);
-            userDAO.save(membership.getUser());
+        for (AMembership membership : findAMemberships(group)) {
+            membership.getLeftEnd().remove(membership);
+            anyObjectDAO.save(membership.getLeftEnd());
+
+            entityManager.remove(membership);
+        }
+        for (UMembership membership : findUMemberships(group)) {
+            membership.getLeftEnd().remove(membership);
+            userDAO.save(membership.getLeftEnd());
 
             entityManager.remove(membership);
         }
@@ -352,76 +202,69 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt
         entityManager.remove(group);
     }
 
-    @Override
-    public void delete(final Long key) {
-        Group group = (Group) findInternal(key);
-        if (group == null) {
-            return;
-        }
+    private void populateTransitiveResources(
+            final Group group, final Any<?, ?, ?> any, final Map<Long, PropagationByResource> result) {
 
-        delete(group);
-    }
+        PropagationByResource propByRes = new PropagationByResource();
+        for (ExternalResource resource : group.getResources()) {
+            if (!any.getResources().contains(resource)) {
+                propByRes.add(ResourceOperation.DELETE, resource.getKey());
+            }
 
-    @Override
-    public Group authFetch(final Long key) {
-        if (key == null) {
-            throw new NotFoundException("Null group id");
+            if (!propByRes.isEmpty()) {
+                result.put(any.getKey(), propByRes);
+            }
         }
+    }
 
-        final Group group = find(key);
-        if (group == null) {
-            throw new NotFoundException("Group " + key);
-        }
+    @Transactional(readOnly = true)
+    @Override
+    public Map<Long, PropagationByResource> findAnyObjectsWithTransitiveResources(final Long groupKey) {
+        Group group = authFind(groupKey);
 
-        Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_READ);
-        boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {
+        Map<Long, PropagationByResource> result = new HashMap<>();
 
-            @Override
-            public boolean evaluate(final String realm) {
-                return group.getRealm().getFullPath().startsWith(realm)
-                        || realm.equals(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
-            }
-        });
-        if (authRealms == null || authRealms.isEmpty() || !authorized) {
-            throw new UnauthorizedException(SubjectType.GROUP, group.getKey());
+        for (AMembership membership : findAMemberships(group)) {
+            populateTransitiveResources(group, membership.getLeftEnd(), result);
         }
 
-        return group;
+        return result;
     }
 
     @Transactional(readOnly = true)
     @Override
-    public Map<Long, PropagationByResource> findUsersWithIndirectResources(final Long groupKey) {
-        Group group = authFetch(groupKey);
+    public Map<Long, PropagationByResource> findUsersWithTransitiveResources(final Long groupKey) {
+        Group group = authFind(groupKey);
 
         Map<Long, PropagationByResource> result = new HashMap<>();
 
-        for (Membership membership : findMemberships(group)) {
-            User user = membership.getUser();
+        for (UMembership membership : findUMemberships(group)) {
+            populateTransitiveResources(group, membership.getLeftEnd(), result);
+        }
+
+        return result;
+    }
 
-            PropagationByResource propByRes = new PropagationByResource();
-            for (ExternalResource resource : group.getResources()) {
-                if (!user.getResources().contains(resource)) {
-                    propByRes.add(ResourceOperation.DELETE, resource.getKey());
-                }
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public void refreshDynMemberships(final AnyObject anyObject) {
+        for (Group role : findAll(SyncopeConstants.FULL_ADMIN_REALMS, -1, -1)) {
+            if (role.getADynMembership() != null && !searchDAO.matches(anyObject,
+                    SearchCondConverter.convert(role.getADynMembership().getFIQLCond()), AnyTypeKind.ANY_OBJECT)) {
 
-                if (!propByRes.isEmpty()) {
-                    result.put(user.getKey(), propByRes);
-                }
+                role.getADynMembership().remove(anyObject);
             }
         }
-
-        return result;
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public void refreshDynMemberships(final User user) {
         for (Group role : findAll(SyncopeConstants.FULL_ADMIN_REALMS, -1, -1)) {
-            if (role.getDynMembership() != null && !searchDAO.matches(user,
-                    SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER)) {
+            if (role.getUDynMembership() != null && !searchDAO.matches(user,
+                    SearchCondConverter.convert(role.getUDynMembership().getFIQLCond()), AnyTypeKind.USER)) {
 
-                role.getDynMembership().removeUser(user);
+                role.getUDynMembership().remove(user);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
deleted file mode 100644
index 998f680..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
+++ /dev/null
@@ -1,104 +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.dao;
-
-import java.util.List;
-import javax.persistence.NoResultException;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public class JPAMembershipDAO extends AbstractDAO<Membership, Long> implements MembershipDAO {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Override
-    public Membership find(final Long key) {
-        return entityManager.find(JPAMembership.class, key);
-    }
-
-    @Override
-    public Membership find(final User user, final Group group) {
-        Query query = entityManager.createQuery(
-                "SELECT e FROM " + JPAMembership.class.getSimpleName()
-                + " e WHERE e.user = :user AND e.group = :group");
-        query.setParameter("user", user);
-        query.setParameter("group", group);
-
-        Membership result = null;
-
-        try {
-            result = (Membership) query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No membership was found for user {} and group {}", user, group, e);
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Membership> findAll() {
-        TypedQuery<Membership> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e", Membership.class);
-        return query.getResultList();
-    }
-
-    @Override
-    public Membership save(final Membership membership) {
-        return entityManager.merge(membership);
-    }
-
-    @Override
-    public void delete(final Long key) {
-        Membership membership = find(key);
-        if (membership == null) {
-            return;
-        }
-
-        membership.getUser().removeMembership(membership);
-        userDAO.save(membership.getUser());
-
-        entityManager.remove(membership);
-    }
-
-    @Override
-    public Membership authFetch(final Long key) {
-        if (key == null) {
-            throw new NotFoundException("Null membership key");
-        }
-
-        Membership membership = find(key);
-        if (membership == null) {
-            throw new NotFoundException("Membership " + key);
-        }
-
-        return membership;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
index b41066c..5e232fd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -19,43 +19,43 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
 import org.springframework.stereotype.Repository;
 
 @Repository
-public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements PlainAttrDAO {
+public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements PlainAttrDAO {
 
-    public <T extends PlainAttr> Class<? extends AbstractPlainAttr> getJPAEntityReference(
+    public <T extends PlainAttr<?>> Class<? extends AbstractPlainAttr<?>> getJPAEntityReference(
             final Class<T> reference) {
 
         return CPlainAttr.class.isAssignableFrom(reference)
                 ? JPACPlainAttr.class
                 : GPlainAttr.class.isAssignableFrom(reference)
                         ? JPAGPlainAttr.class
-                        : MPlainAttr.class.isAssignableFrom(reference)
-                                ? JPAMPlainAttr.class
+                        : APlainAttr.class.isAssignableFrom(reference)
+                                ? JPAAPlainAttr.class
                                 : UPlainAttr.class.isAssignableFrom(reference)
                                         ? JPAUPlainAttr.class
                                         : null;
     }
 
     @Override
-    public <T extends PlainAttr> T find(final Long key, final Class<T> reference) {
+    public <T extends PlainAttr<?>> T find(final Long key, final Class<T> reference) {
         return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
     }
 
     @Override
-    public <T extends PlainAttr> void delete(final Long key, final Class<T> reference) {
+    public <T extends PlainAttr<?>> void delete(final Long key, final Class<T> reference) {
         T attribute = find(key, reference);
         if (attribute == null) {
             return;
@@ -66,9 +66,9 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements Pla
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T extends PlainAttr> void delete(final T plainAttr) {
+    public <T extends PlainAttr<?>> void delete(final T plainAttr) {
         if (plainAttr.getOwner() != null) {
-            ((Attributable<T, ?, ?>) plainAttr.getOwner()).removePlainAttr(plainAttr);
+            ((Any<T, ?, ?>) plainAttr.getOwner()).remove(plainAttr);
         }
 
         entityManager.remove(plainAttr);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
index 4b99051..655decd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -22,19 +22,19 @@ import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
 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.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
@@ -55,10 +55,10 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
                                 ? JPAGPlainAttrValue.class
                                 : reference.equals(GPlainAttrUniqueValue.class)
                                         ? JPAGPlainAttrUniqueValue.class
-                                        : reference.equals(MPlainAttrValue.class)
-                                                ? JPAMPlainAttrValue.class
-                                                : reference.equals(MPlainAttrUniqueValue.class)
-                                                        ? JPAMPlainAttrUniqueValue.class
+                                        : reference.equals(APlainAttrValue.class)
+                                                ? JPAAPlainAttrValue.class
+                                                : reference.equals(APlainAttrUniqueValue.class)
+                                                        ? JPAAPlainAttrUniqueValue.class
                                                         : reference.equals(UPlainAttrValue.class)
                                                                 ? JPAUPlainAttrValue.class
                                                                 : reference.equals(UPlainAttrUniqueValue.class)
@@ -96,7 +96,7 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
     @Override
     public <T extends PlainAttrValue> void delete(final T attrValue) {
         if (attrValue.getAttr() != null) {
-            attrValue.getAttr().removeValue(attrValue);
+            attrValue.getAttr().remove(attrValue);
         }
 
         entityManager.remove(attrValue);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index cc7df33..a922946 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -20,29 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+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.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -53,46 +40,25 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
     private PlainAttrDAO plainAttrDAO;
 
     @Autowired
-    private AttrTemplateDAO<PlainSchema> attrTemplateDAO;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
-    private <T extends PlainSchema> Class<? extends AbstractPlainSchema> getJPAEntityReference(
-            final Class<T> reference) {
-
-        return CPlainSchema.class.isAssignableFrom(reference)
-                ? JPACPlainSchema.class
-                : GPlainSchema.class.isAssignableFrom(reference)
-                        ? JPAGPlainSchema.class
-                        : MPlainSchema.class.isAssignableFrom(reference)
-                                ? JPAMPlainSchema.class
-                                : UPlainSchema.class.isAssignableFrom(reference)
-                                        ? JPAUPlainSchema.class
-                                        : null;
-    }
-
     @Override
-    public <T extends PlainSchema> T find(final String key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+    public PlainSchema find(final String key) {
+        return entityManager.find(JPAPlainSchema.class, key);
     }
 
     @Override
-    public <T extends PlainSchema> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
-                "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+    public List<PlainSchema> findAll() {
+        TypedQuery<PlainSchema> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class);
         return query.getResultList();
     }
 
     @Override
-    public <T extends PlainAttr> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
-        final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+    public <T extends PlainAttr<?>> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()).
-                append(" e WHERE e.");
-        if (GPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) {
-            queryString.append("template.");
-        }
-        queryString.append("schema=:schema");
+                append(" e WHERE e.schema=:schema");
 
         TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
@@ -101,45 +67,28 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
     }
 
     @Override
-    public <T extends PlainSchema> T save(final T schema) {
+    public PlainSchema save(final PlainSchema schema) {
         return entityManager.merge(schema);
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public void delete(final String key, final AttributableUtils attributableUtil) {
-        PlainSchema schema = find(key, attributableUtil.plainSchemaClass());
+    public void delete(final String key) {
+        PlainSchema schema = find(key);
         if (schema == null) {
             return;
         }
 
-        CollectionUtils.forAllDo(findAttrs(schema, attributableUtil.plainAttrClass()), new Closure<PlainAttr>() {
+        AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory();
+        for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
 
-            @Override
-            public void execute(final PlainAttr input) {
-                plainAttrDAO.delete(input.getKey(), attributableUtil.plainAttrClass());
+            for (PlainAttr<?> attr : findAttrs(schema, anyUtils.plainAttrClass())) {
+                plainAttrDAO.delete(attr.getKey(), anyUtils.plainAttrClass());
             }
 
-        });
-
-        if (attributableUtil.getType() == AttributableType.GROUP
-                || attributableUtil.getType() == AttributableType.MEMBERSHIP) {
-
-            CollectionUtils.forAllDo(attrTemplateDAO.
-                    findBySchemaName(schema.getKey(), attributableUtil.plainAttrTemplateClass()).iterator(),
-                    new Closure<Number>() {
-
-                        @Override
-                        public void execute(final Number input) {
-                            attrTemplateDAO.delete(input.longValue(), attributableUtil.plainAttrTemplateClass());
-                        }
-
-                    });
+            resourceDAO.deleteMapping(key, anyUtils.plainIntMappingType());
         }
 
-        resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), UMappingItem.class);
-        resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), GMappingItem.class);
-
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
----------------------------------------------------------------------
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 1007ac4..176cfbd 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
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.types.PolicyType;
 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.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Realm;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index c195bd9..5f600b6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -22,10 +22,10 @@ import java.util.List;
 import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -39,7 +39,7 @@ import org.springframework.transaction.annotation.Transactional;
 public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Autowired
-    private SubjectSearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     @Override
     public Role find(final Long key) {
@@ -82,11 +82,11 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
         // refresh dynaminc memberships
         if (role.getDynMembership() != null) {
             List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                    SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER);
+                    SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), AnyTypeKind.USER);
 
-            role.getDynMembership().getUsers().clear();
+            role.getDynMembership().getMembers().clear();
             for (User user : matchingUsers) {
-                role.getDynMembership().addUser(user);
+                role.getDynMembership().add(user);
             }
         }
 
@@ -113,9 +113,9 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
     public void refreshDynMemberships(final User user) {
         for (Role role : findAll()) {
             if (role.getDynMembership() != null && !searchDAO.matches(user,
-                    SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER)) {
+                    SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), AnyTypeKind.USER)) {
 
-                role.getDynMembership().removeUser(user);
+                role.getDynMembership().remove(user);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
deleted file mode 100644
index b4cbad8..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java
+++ /dev/null
@@ -1,778 +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.dao;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.persistence.Entity;
-import javax.persistence.Query;
-import javax.persistence.TemporalType;
-import javax.validation.ValidationException;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.misc.RealmUtils;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.GroupCond;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
-import org.springframework.util.ReflectionUtils;
-
-@Repository
-public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> implements SubjectSearchDAO {
-
-    private static final String EMPTY_ATTR_QUERY = "SELECT subject_id FROM user_search_attr WHERE 1=2";
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private PlainSchemaDAO schemaDAO;
-
-    @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
-
-    private String getAdminRealmsFilter(final Set<String> adminRealms, final SearchSupport svs) {
-        Set<Long> realmKeys = new HashSet<>();
-        for (String realmPath : RealmUtils.normalize(adminRealms)) {
-            Realm realm = realmDAO.find(realmPath);
-            if (realm == null) {
-                LOG.warn("Ignoring invalid realm {}", realmPath);
-            } else {
-                CollectionUtils.collect(realmDAO.findDescendants(realm), new Transformer<Realm, Long>() {
-
-                    @Override
-                    public Long transform(final Realm descendant) {
-                        return descendant.getKey();
-                    }
-                }, realmKeys);
-            }
-        }
-
-        StringBuilder adminRealmFilter = new StringBuilder().
-                append("SELECT subject_id FROM ").append(svs.field().name).
-                append(" WHERE realm_id IN (SELECT id AS realm_id FROM Realm");
-
-        boolean firstRealm = true;
-        for (Long realmKey : realmKeys) {
-            if (firstRealm) {
-                adminRealmFilter.append(" WHERE");
-                firstRealm = false;
-            } else {
-                adminRealmFilter.append(" OR");
-            }
-            adminRealmFilter.append(" id = ").append(realmKey);
-        }
-
-        adminRealmFilter.append(')');
-
-        return adminRealmFilter.toString();
-    }
-
-    @Override
-    public int count(final Set<String> adminRealms, final SearchCond searchCondition, final SubjectType type) {
-        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
-
-        // 1. get the query string from the search condition
-        SearchSupport svs = new SearchSupport(type);
-        StringBuilder queryString = getQuery(searchCondition, parameters, type, svs);
-
-        // 2. take into account administrative realms
-        queryString.insert(0, "SELECT u.subject_id FROM (");
-        queryString.append(") u WHERE subject_id IN (");
-        queryString.append(getAdminRealmsFilter(adminRealms, svs)).append(')');
-
-        // 3. prepare the COUNT query
-        queryString.insert(0, "SELECT COUNT(subject_id) FROM (");
-        queryString.append(") count_subject_id");
-
-        Query countQuery = entityManager.createNativeQuery(queryString.toString());
-        fillWithParameters(countQuery, parameters);
-
-        LOG.debug("Native count query\n{}\nwith parameters\n{}", queryString.toString(), parameters);
-
-        int result = ((Number) countQuery.getSingleResult()).intValue();
-        LOG.debug("Native count query result: {}", result);
-
-        return result;
-    }
-
-    @Override
-    public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<String> adminRealms, final SearchCond searchCondition, final SubjectType type) {
-
-        return search(adminRealms, searchCondition, Collections.<OrderByClause>emptyList(), type);
-    }
-
-    @Override
-    public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<String> adminRealms, final SearchCond searchCondition, final List<OrderByClause> orderBy,
-            final SubjectType type) {
-
-        return search(adminRealms, searchCondition, -1, -1, orderBy, type);
-    }
-
-    @Override
-    public <T extends Subject<?, ?, ?>> List<T> search(
-            final Set<String> adminRealms, final SearchCond searchCondition, final int page, final int itemsPerPage,
-            final List<OrderByClause> orderBy, final SubjectType type) {
-
-        List<T> result = Collections.<T>emptyList();
-
-        if (adminRealms != null && !adminRealms.isEmpty()) {
-            LOG.debug("Search condition:\n{}", searchCondition);
-
-            if (searchCondition != null && searchCondition.isValid()) {
-                try {
-                    result = doSearch(adminRealms, searchCondition, page, itemsPerPage, orderBy, type);
-                } catch (Exception e) {
-                    LOG.error("While searching for {}", type, e);
-                }
-            } else {
-                LOG.error("Invalid search condition:\n{}", searchCondition);
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends Subject<?, ?, ?>> boolean matches(
-            final T subject, final SearchCond searchCondition, final SubjectType type) {
-
-        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
-
-        // 1. get the query string from the search condition
-        SearchSupport svs = new SearchSupport(type);
-        StringBuilder queryString = getQuery(searchCondition, parameters, type, svs);
-
-        boolean matches;
-        if (queryString.length() == 0) {
-            // Could be empty: got into a group search with a single membership condition ...
-            matches = false;
-        } else {
-            // 2. take into account the passed user
-            queryString.insert(0, "SELECT u.subject_id FROM (");
-            queryString.append(") u WHERE subject_id=?").append(setParameter(parameters, subject.getKey()));
-
-            // 3. prepare the search query
-            Query query = entityManager.createNativeQuery(queryString.toString());
-
-            // 4. populate the search query with parameter values
-            fillWithParameters(query, parameters);
-
-            // 5. executes query
-            matches = !query.getResultList().isEmpty();
-        }
-
-        return matches;
-    }
-
-    private int setParameter(final List<Object> parameters, final Object parameter) {
-        int key;
-        synchronized (parameters) {
-            parameters.add(parameter);
-            key = parameters.size();
-        }
-
-        return key;
-    }
-
-    private void fillWithParameters(final Query query, final List<Object> parameters) {
-        for (int i = 0; i < parameters.size(); i++) {
-            if (parameters.get(i) instanceof Date) {
-                query.setParameter(i + 1, (Date) parameters.get(i), TemporalType.TIMESTAMP);
-            } else if (parameters.get(i) instanceof Boolean) {
-                query.setParameter(i + 1, ((Boolean) parameters.get(i))
-                        ? 1
-                        : 0);
-            } else {
-                query.setParameter(i + 1, parameters.get(i));
-            }
-        }
-    }
-
-    private StringBuilder buildSelect(final OrderBySupport orderBySupport) {
-        final StringBuilder select = new StringBuilder("SELECT u.subject_id");
-
-        for (OrderBySupport.Item obs : orderBySupport.items) {
-            select.append(',').append(obs.select);
-        }
-        select.append(" FROM ");
-
-        return select;
-    }
-
-    private StringBuilder buildWhere(final OrderBySupport orderBySupport) {
-        final StringBuilder where = new StringBuilder(" u");
-        for (SearchSupport.SearchView searchView : orderBySupport.views) {
-            where.append(',').append(searchView.name).append(' ').append(searchView.alias);
-        }
-        where.append(" WHERE ");
-        for (SearchSupport.SearchView searchView : orderBySupport.views) {
-            where.append("u.subject_id=").append(searchView.alias).append(".subject_id AND ");
-        }
-
-        for (OrderBySupport.Item obs : orderBySupport.items) {
-            if (StringUtils.isNotBlank(obs.where)) {
-                where.append(obs.where).append(" AND ");
-            }
-        }
-        where.append("u.subject_id IN (");
-
-        return where;
-    }
-
-    private StringBuilder buildOrderBy(final OrderBySupport orderBySupport) {
-        final StringBuilder orderBy = new StringBuilder();
-
-        for (OrderBySupport.Item obs : orderBySupport.items) {
-            orderBy.append(obs.orderBy).append(',');
-        }
-        if (!orderBySupport.items.isEmpty()) {
-            orderBy.insert(0, " ORDER BY ");
-            orderBy.deleteCharAt(orderBy.length() - 1);
-        }
-
-        return orderBy;
-    }
-
-    private OrderBySupport parseOrderBy(final SubjectType type, final SearchSupport svs,
-            final List<OrderByClause> orderByClauses) {
-
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType());
-
-        OrderBySupport orderBySupport = new OrderBySupport();
-
-        for (OrderByClause clause : orderByClauses) {
-            OrderBySupport.Item obs = new OrderBySupport.Item();
-
-            // Manage difference among external key attribute and internal JPA @Id
-            String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
-
-            Field subjectField = ReflectionUtils.findField(attrUtils.attributableClass(), fieldName);
-            if (subjectField == null) {
-                PlainSchema schema = schemaDAO.find(fieldName, attrUtils.plainSchemaClass());
-                if (schema != null) {
-                    if (schema.isUniqueConstraint()) {
-                        orderBySupport.views.add(svs.uniqueAttr());
-
-                        obs.select = new StringBuilder().
-                                append(svs.uniqueAttr().alias).append('.').append(svs.fieldName(schema.getType())).
-                                append(" AS ").append(fieldName).toString();
-                        obs.where = new StringBuilder().
-                                append(svs.uniqueAttr().alias).
-                                append(".schema_name='").append(fieldName).append("'").toString();
-                        obs.orderBy = fieldName + " " + clause.getDirection().name();
-                    } else {
-                        orderBySupport.views.add(svs.attr());
-
-                        obs.select = new StringBuilder().
-                                append(svs.attr().alias).append('.').append(svs.fieldName(schema.getType())).
-                                append(" AS ").append(fieldName).toString();
-                        obs.where = new StringBuilder().
-                                append(svs.attr().alias).
-                                append(".schema_name='").append(fieldName).append("'").toString();
-                        obs.orderBy = fieldName + " " + clause.getDirection().name();
-                    }
-                }
-            } else {
-                orderBySupport.views.add(svs.field());
-
-                obs.select = svs.field().alias + "." + fieldName;
-                obs.where = StringUtils.EMPTY;
-                obs.orderBy = svs.field().alias + "." + fieldName + " " + clause.getDirection().name();
-            }
-
-            if (obs.isEmpty()) {
-                LOG.warn("Cannot build any valid clause from {}", clause);
-            } else {
-                orderBySupport.items.add(obs);
-            }
-        }
-
-        return orderBySupport;
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T extends Subject<?, ?, ?>> List<T> doSearch(final Set<String> adminRealms,
-            final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy,
-            final SubjectType type) {
-
-        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
-
-        // 1. get the query string from the search condition
-        SearchSupport svs = new SearchSupport(type);
-        StringBuilder queryString = getQuery(nodeCond, parameters, type, svs);
-
-        // 2. take into account administrative groups and ordering
-        OrderBySupport orderBySupport = parseOrderBy(type, svs, orderBy);
-        if (queryString.charAt(0) == '(') {
-            queryString.insert(0, buildSelect(orderBySupport));
-            queryString.append(buildWhere(orderBySupport));
-        } else {
-            queryString.insert(0, buildSelect(orderBySupport).append('('));
-            queryString.append(')').append(buildWhere(orderBySupport));
-        }
-        queryString.
-                append(getAdminRealmsFilter(adminRealms, svs)).append(')').
-                append(buildOrderBy(orderBySupport));
-
-        // 3. prepare the search query
-        Query query = entityManager.createNativeQuery(queryString.toString());
-
-        // 4. page starts from 1, while setFirtResult() starts from 0
-        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
-
-        if (itemsPerPage >= 0) {
-            query.setMaxResults(itemsPerPage);
-        }
-
-        // 5. populate the search query with parameter values
-        fillWithParameters(query, parameters);
-
-        LOG.debug("Native query\n{}\nwith parameters\n{}", queryString.toString(), parameters);
-
-        // 6. Prepare the result (avoiding duplicates)
-        List<T> result = new ArrayList<>();
-
-        for (Object subjectId : query.getResultList()) {
-            long actualId;
-            if (subjectId instanceof Object[]) {
-                actualId = ((Number) ((Object[]) subjectId)[0]).longValue();
-            } else {
-                actualId = ((Number) subjectId).longValue();
-            }
-
-            T subject = type == SubjectType.USER
-                    ? (T) userDAO.find(actualId)
-                    : (T) groupDAO.find(actualId);
-            if (subject == null) {
-                LOG.error("Could not find {} with id {}, even though returned by the native query",
-                        type, actualId);
-            } else {
-                if (!result.contains(subject)) {
-                    result.add(subject);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters,
-            final SubjectType type, final SearchSupport svs) {
-
-        StringBuilder query = new StringBuilder();
-
-        switch (nodeCond.getType()) {
-
-            case LEAF:
-            case NOT_LEAF:
-                if (nodeCond.getGroupCond() != null && SubjectType.USER == type) {
-                    query.append(getQuery(nodeCond.getGroupCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
-                }
-                if (nodeCond.getRoleCond() != null && SubjectType.USER == type) {
-                    query.append(getQuery(nodeCond.getRoleCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
-                }
-                if (nodeCond.getResourceCond() != null) {
-                    query.append(getQuery(nodeCond.getResourceCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
-                }
-                if (nodeCond.getAttributeCond() != null) {
-                    query.append(getQuery(nodeCond.getAttributeCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
-                }
-                if (nodeCond.getSubjectCond() != null) {
-                    query.append(getQuery(nodeCond.getSubjectCond(),
-                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
-                }
-                break;
-
-            case AND:
-                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
-                        append(" AND subject_id IN ( ").
-                        append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
-                        append(")");
-                break;
-
-            case OR:
-                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
-                        append(" OR subject_id IN ( ").
-                        append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
-                        append(")");
-                break;
-
-            default:
-        }
-
-        return query;
-    }
-
-    private String getQuery(final GroupCond cond, final boolean not, final List<Object> parameters,
-            final SearchSupport svs) {
-
-        StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM ").
-                append(svs.field().name).append(" WHERE ");
-
-        if (not) {
-            query.append("subject_id NOT IN (");
-        } else {
-            query.append("subject_id IN (");
-        }
-
-        query.append("SELECT DISTINCT subject_id ").append("FROM ").
-                append(svs.membership().name).append(" WHERE ").
-                append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
-                append(')');
-
-        if (not) {
-            query.append("AND subject_id NOT IN (");
-        } else {
-            query.append("OR subject_id IN (");
-        }
-
-        query.append("SELECT DISTINCT subject_id ").append("FROM ").
-                append(svs.dyngroupmembership().name).append(" WHERE ").
-                append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
-                append(')');
-
-        return query.toString();
-    }
-
-    private String getQuery(final RoleCond cond, final boolean not, final List<Object> parameters,
-            final SearchSupport svs) {
-
-        StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM ").
-                append(svs.field().name).append(" WHERE ");
-
-        if (not) {
-            query.append("subject_id NOT IN (");
-        } else {
-            query.append("subject_id IN (");
-        }
-
-        query.append("SELECT DISTINCT subject_id ").append("FROM ").
-                append(svs.role().name).append(" WHERE ").
-                append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
-                append(')');
-
-        if (not) {
-            query.append("AND subject_id NOT IN (");
-        } else {
-            query.append("OR subject_id IN (");
-        }
-
-        query.append("SELECT DISTINCT subject_id ").append("FROM ").
-                append(svs.dynrolemembership().name).append(" WHERE ").
-                append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
-                append(')');
-
-        return query.toString();
-    }
-
-    private String getQuery(final ResourceCond cond, final boolean not, final List<Object> parameters,
-            final SubjectType type, final SearchSupport svs) {
-
-        final StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM ").
-                append(svs.field().name).append(" WHERE ");
-
-        if (not) {
-            query.append("subject_id NOT IN (");
-        } else {
-            query.append("subject_id IN (");
-        }
-
-        query.append("SELECT DISTINCT subject_id FROM ").
-                append(svs.resource().name).
-                append(" WHERE resource_name=?").
-                append(setParameter(parameters, cond.getResourceName()));
-
-        if (type == SubjectType.USER) {
-            query.append(" UNION SELECT DISTINCT subject_id FROM ").
-                    append(svs.groupResource().name).
-                    append(" WHERE resource_name=?").
-                    append(setParameter(parameters, cond.getResourceName()));
-        }
-
-        query.append(')');
-
-        return query.toString();
-    }
-
-    private void fillAttributeQuery(final StringBuilder query, final PlainAttrValue attrValue,
-            final PlainSchema schema, final AttributeCond cond, final boolean not,
-            final List<Object> parameters, final SearchSupport svs) {
-
-        String column = (cond instanceof SubjectCond)
-                ? cond.getSchema()
-                : "' AND " + svs.fieldName(schema.getType());
-
-        switch (cond.getType()) {
-
-            case ISNULL:
-                query.append(column).append(not
-                        ? " IS NOT NULL"
-                        : " IS NULL");
-                break;
-
-            case ISNOTNULL:
-                query.append(column).append(not
-                        ? " IS NULL"
-                        : " IS NOT NULL");
-                break;
-
-            case LIKE:
-                if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
-                    query.append(column);
-                    if (not) {
-                        query.append(" NOT ");
-                    }
-                    query.append(" LIKE ?").append(setParameter(parameters, cond.getExpression()));
-                } else {
-                    if (!(cond instanceof SubjectCond)) {
-                        query.append("' AND");
-                    }
-                    query.append(" 1=2");
-                    LOG.error("LIKE is only compatible with string or enum schemas");
-                }
-                break;
-
-            case EQ:
-                query.append(column);
-                if (not) {
-                    query.append("<>");
-                } else {
-                    query.append('=');
-                }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
-                break;
-
-            case GE:
-                query.append(column);
-                if (not) {
-                    query.append('<');
-                } else {
-                    query.append(">=");
-                }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
-                break;
-
-            case GT:
-                query.append(column);
-                if (not) {
-                    query.append("<=");
-                } else {
-                    query.append('>');
-                }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
-                break;
-
-            case LE:
-                query.append(column);
-                if (not) {
-                    query.append('>');
-                } else {
-                    query.append("<=");
-                }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
-                break;
-
-            case LT:
-                query.append(column);
-                if (not) {
-                    query.append(">=");
-                } else {
-                    query.append('<');
-                }
-                query.append('?').append(setParameter(parameters, attrValue.getValue()));
-                break;
-
-            default:
-        }
-    }
-
-    private String getQuery(final AttributeCond cond, final boolean not, final List<Object> parameters,
-            final SubjectType type, final SearchSupport svs) {
-
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType());
-
-        PlainSchema schema = schemaDAO.find(cond.getSchema(), attrUtils.plainSchemaClass());
-        if (schema == null) {
-            LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
-            return EMPTY_ATTR_QUERY;
-        }
-
-        PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
-        try {
-            if (cond.getType() != AttributeCond.Type.LIKE && cond.getType() != AttributeCond.Type.ISNULL
-                    && cond.getType() != AttributeCond.Type.ISNOTNULL) {
-
-                schema.getValidator().validate(cond.getExpression(), attrValue);
-            }
-        } catch (ValidationException e) {
-            LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
-            return EMPTY_ATTR_QUERY;
-        }
-
-        StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM ");
-        if (cond.getType() == AttributeCond.Type.ISNOTNULL) {
-            query.append(svs.field().name).
-                    append(" WHERE subject_id NOT IN (SELECT subject_id FROM ").
-                    append(svs.nullAttr().name).
-                    append(" WHERE schema_name='").append(schema.getKey()).append("')");
-        } else {
-            if (cond.getType() == AttributeCond.Type.ISNULL) {
-                query.append(svs.nullAttr().name).
-                        append(" WHERE schema_name='").append(schema.getKey()).append("'");
-            } else {
-                if (schema.isUniqueConstraint()) {
-                    query.append(svs.uniqueAttr().name);
-                } else {
-                    query.append(svs.attr().name);
-                }
-                query.append(" WHERE schema_name='").append(schema.getKey());
-
-                fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
-            }
-        }
-
-        return query.toString();
-    }
-
-    @SuppressWarnings("rawtypes")
-    private String getQuery(final SubjectCond cond, final boolean not, final List<Object> parameters,
-            final SubjectType type, final SearchSupport svs) {
-
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType());
-
-        // Keeps track of difference between entity's getKey() and JPA @Id fields
-        if ("key".equals(cond.getSchema())) {
-            cond.setSchema("id");
-        }
-
-        Field subjectField = ReflectionUtils.findField(attrUtils.attributableClass(), cond.getSchema());
-        if (subjectField == null) {
-            LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
-            return EMPTY_ATTR_QUERY;
-        }
-
-        PlainSchema schema = attrUtils.newPlainSchema();
-        schema.setKey(subjectField.getName());
-        for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
-            if (subjectField.getType().isAssignableFrom(attrSchemaType.getType())) {
-                schema.setType(attrSchemaType);
-            }
-        }
-
-        // Deal with subject Integer fields logically mapping to boolean values
-        // (JPAGroup.inheritPlainAttrs, for example)
-        boolean foundBooleanMin = false;
-        boolean foundBooleanMax = false;
-        if (Integer.class.equals(subjectField.getType())) {
-            for (Annotation annotation : subjectField.getAnnotations()) {
-                if (Min.class.equals(annotation.annotationType())) {
-                    foundBooleanMin = ((Min) annotation).value() == 0;
-                } else if (Max.class.equals(annotation.annotationType())) {
-                    foundBooleanMax = ((Max) annotation).value() == 1;
-                }
-            }
-        }
-        if (foundBooleanMin && foundBooleanMax) {
-            schema.setType(AttrSchemaType.Boolean);
-        }
-
-        // Deal with subject fields representing relationships to other entities
-        if (subjectField.getType().getAnnotation(Entity.class) != null) {
-            Method relMethod = null;
-            try {
-                relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
-            } catch (Exception e) {
-                LOG.error("Could not find {}#getKey", subjectField.getType(), e);
-            }
-
-            if (relMethod != null) {
-                if (Long.class.isAssignableFrom(relMethod.getReturnType())) {
-                    cond.setSchema(cond.getSchema() + "_id");
-                    schema.setType(AttrSchemaType.Long);
-                }
-                if (String.class.isAssignableFrom(relMethod.getReturnType())) {
-                    cond.setSchema(cond.getSchema() + "_name");
-                    schema.setType(AttrSchemaType.String);
-                }
-            }
-        }
-
-        PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
-        if (cond.getType() != AttributeCond.Type.LIKE
-                && cond.getType() != AttributeCond.Type.ISNULL
-                && cond.getType() != AttributeCond.Type.ISNOTNULL) {
-
-            try {
-                schema.getValidator().validate(cond.getExpression(), attrValue);
-            } catch (ValidationException e) {
-                LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
-                return EMPTY_ATTR_QUERY;
-            }
-        }
-
-        final StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM ").
-                append(svs.field().name).append(" WHERE ");
-
-        fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
-
-        return query.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
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 d90ddbd..ff93071 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
@@ -26,7 +26,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.types.TaskType;
 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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;


[17/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyAbout.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyAbout.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyAbout.java
new file mode 100644
index 0000000..4d7e9c5
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyAbout.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Notification;
+
+@Entity
+@Table(name = JPAAnyAbout.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "notification_id", "anyType_name" }))
+public class JPAAnyAbout extends AbstractEntity<Long> implements AnyAbout {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyAbout";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPANotification notification;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String about;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Notification getNotification() {
+        return notification;
+    }
+
+    @Override
+    public void setNotification(final Notification notification) {
+        checkType(notification, JPANotification.class);
+        this.notification = (JPANotification) notification;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public String get() {
+        return about;
+    }
+
+    @Override
+    public void set(final String filter) {
+        this.about = filter;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
new file mode 100644
index 0000000..2615520
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+
+@Entity
+@Table(name = JPAAnyType.TABLE)
+@Cacheable
+public class JPAAnyType extends AbstractEntity<String> implements AnyType {
+
+    private static final long serialVersionUID = 2668267884059219835L;
+
+    public static final String TABLE = "AnyType";
+
+    @Id
+    private String name;
+
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    private AnyTypeKind kind;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyType_name"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyTypeClass_name"))
+    private List<JPAAnyTypeClass> classes = new ArrayList<>();
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public AnyTypeKind getKind() {
+        return kind;
+    }
+
+    @Override
+    public void setKind(final AnyTypeKind kind) {
+        this.kind = kind;
+    }
+
+    @Override
+    public boolean add(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        return this.classes.add((JPAAnyTypeClass) anyTypeClass);
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        return this.classes.remove((JPAAnyTypeClass) anyTypeClass);
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getClasses() {
+        return classes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
new file mode 100644
index 0000000..5c52097
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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;
+
+@Entity
+@Table(name = JPAAnyTypeClass.TABLE)
+@Cacheable
+public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeClass {
+
+    private static final long serialVersionUID = -1750247153774475453L;
+
+    public static final String TABLE = "AnyTypeClass";
+
+    @Id
+    private String name;
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyTypeClass_name"),
+            inverseJoinColumns =
+            @JoinColumn(name = "plainSchema_name"))
+    private List<JPAPlainSchema> plainSchemas = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyTypeClass_name"),
+            inverseJoinColumns =
+            @JoinColumn(name = "derSchema_name"))
+    private List<JPADerSchema> derSchemas = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyTypeClass_name"),
+            inverseJoinColumns =
+            @JoinColumn(name = "virSchema_name"))
+    private List<JPAVirSchema> virSchemas = new ArrayList<>();
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean add(final PlainSchema facet) {
+        checkType(facet, JPAPlainSchema.class);
+        return this.plainSchemas.add((JPAPlainSchema) facet);
+    }
+
+    @Override
+    public boolean remove(final PlainSchema facet) {
+        checkType(facet, JPAPlainSchema.class);
+        return this.plainSchemas.remove((JPAPlainSchema) facet);
+    }
+
+    @Override
+    public List<? extends PlainSchema> getPlainSchemas() {
+        return plainSchemas;
+    }
+
+    @Override
+    public boolean add(final DerSchema facet) {
+        checkType(facet, JPADerSchema.class);
+        return this.derSchemas.add((JPADerSchema) facet);
+    }
+
+    @Override
+    public boolean remove(final DerSchema facet) {
+        checkType(facet, JPAPlainSchema.class);
+        return this.derSchemas.remove((JPADerSchema) facet);
+    }
+
+    @Override
+    public List<? extends DerSchema> getDerSchemas() {
+        return derSchemas;
+    }
+
+    @Override
+    public boolean add(final VirSchema facet) {
+        checkType(facet, JPAVirSchema.class);
+        return this.virSchemas.add((JPAVirSchema) facet);
+    }
+
+    @Override
+    public boolean remove(final VirSchema facet) {
+        checkType(facet, JPAPlainSchema.class);
+        return this.virSchemas.remove((JPAVirSchema) facet);
+    }
+
+    @Override
+    public List<? extends VirSchema> getVirSchemas() {
+        return virSchemas;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..989c642
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -0,0 +1,488 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
+
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class JPAAnyUtils implements AnyUtils {
+
+    private final AnyTypeKind anyTypeKind;
+
+    protected JPAAnyUtils(final AnyTypeKind typeKind) {
+        this.anyTypeKind = typeKind;
+    }
+
+    @Override
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
+    }
+
+    @Override
+    public <T extends Any<?, ?, ?>> Class<T> anyClass() {
+        Class result;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = JPAGroup.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAAnyObject.class;
+                break;
+
+            case USER:
+            default:
+                result = JPAUser.class;
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttr<?>> Class<T> plainAttrClass() {
+        Class result = null;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = JPAGPlainAttr.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAAPlainAttr.class;
+                break;
+
+            case USER:
+            default:
+                result = JPAUPlainAttr.class;
+                break;
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttr<?>> T newPlainAttr() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new JPAUPlainAttr();
+                break;
+
+            case GROUP:
+                result = (T) new JPAGPlainAttr();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new JPAAPlainAttr();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttrValue> Class<T> plainAttrValueClass() {
+        Class result;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = JPAGPlainAttrValue.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAAPlainAttrValue.class;
+                break;
+
+            case USER:
+            default:
+                result = JPAUPlainAttrValue.class;
+                break;
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttrValue> T newPlainAttrValue() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new JPAUPlainAttrValue();
+                break;
+
+            case GROUP:
+                result = (T) new JPAGPlainAttrValue();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new JPAAPlainAttrValue();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass() {
+        Class result;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = JPAGPlainAttrUniqueValue.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAAPlainAttrUniqueValue.class;
+                break;
+
+            case USER:
+            default:
+                result = JPAUPlainAttrUniqueValue.class;
+                break;
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends PlainAttrValue> T newPlainAttrUniqueValue() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new JPAUPlainAttrUniqueValue();
+                break;
+
+            case GROUP:
+                result = (T) new JPAGPlainAttrUniqueValue();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new JPAAPlainAttrUniqueValue();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends DerAttr<?>> Class<T> derAttrClass() {
+        Class result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = JPAUDerAttr.class;
+                break;
+
+            case GROUP:
+                result = JPAGDerAttr.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAADerAttr.class;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends DerAttr<?>> T newDerAttr() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new JPAUDerAttr();
+                break;
+
+            case GROUP:
+                result = (T) new JPAGDerAttr();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new JPAADerAttr();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends VirAttr<?>> Class<T> virAttrClass() {
+        Class result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = JPAUVirAttr.class;
+                break;
+
+            case GROUP:
+                result = JPAGVirAttr.class;
+                break;
+
+            case ANY_OBJECT:
+                result = JPAAVirAttr.class;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends VirAttr<?>> T newVirAttr() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new JPAUVirAttr();
+                break;
+
+            case GROUP:
+                result = (T) new JPAGVirAttr();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new JPAAVirAttr();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public MappingItem getConnObjectKeyItem(final Provision provision) {
+        Mapping mapping = null;
+        if (provision != null) {
+            mapping = provision.getMapping();
+        }
+
+        return mapping == null
+                ? null
+                : mapping.getConnObjectKeyItem();
+    }
+
+    @Override
+    public String getConnObjectLink(final Provision provision) {
+        Mapping mapping = null;
+        if (provision != null) {
+            mapping = provision.getMapping();
+        }
+
+        return mapping == null
+                ? null
+                : mapping.getConnObjectLink();
+    }
+
+    @Override
+    public List<MappingItem> getMappingItems(final Provision provision, final MappingPurpose purpose) {
+        List<? extends MappingItem> items = Collections.<MappingItem>emptyList();
+        if (provision != null) {
+            items = provision.getMapping().getItems();
+        }
+
+        List<MappingItem> result = new ArrayList<>();
+
+        switch (purpose) {
+            case SYNCHRONIZATION:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.PROPAGATION != item.getPurpose()
+                            && MappingPurpose.NONE != item.getPurpose()) {
+
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case PROPAGATION:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
+                            && MappingPurpose.NONE != item.getPurpose()) {
+
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case BOTH:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.NONE != item.getPurpose()) {
+                        result.add(item);
+                    }
+                }
+                break;
+
+            case NONE:
+                for (MappingItem item : items) {
+                    if (MappingPurpose.NONE == item.getPurpose()) {
+                        result.add(item);
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public IntMappingType plainIntMappingType() {
+        IntMappingType result = null;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = IntMappingType.GroupPlainSchema;
+                break;
+
+            case ANY_OBJECT:
+                result = IntMappingType.AnyPlainSchema;
+                break;
+
+            case USER:
+                result = IntMappingType.UserPlainSchema;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public IntMappingType derIntMappingType() {
+        IntMappingType result = null;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = IntMappingType.GroupDerivedSchema;
+                break;
+
+            case ANY_OBJECT:
+                result = IntMappingType.AnyDerivedSchema;
+                break;
+
+            case USER:
+                result = IntMappingType.UserDerivedSchema;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public IntMappingType virIntMappingType() {
+        IntMappingType result = null;
+
+        switch (anyTypeKind) {
+            case GROUP:
+                result = IntMappingType.GroupVirtualSchema;
+                break;
+
+            case ANY_OBJECT:
+                result = IntMappingType.AnyVirtualSchema;
+                break;
+
+            case USER:
+                result = IntMappingType.UserVirtualSchema;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends AnyTO> T newAnyTO() {
+        T result = null;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = (T) new UserTO();
+                break;
+
+            case GROUP:
+                result = (T) new GroupTO();
+                break;
+
+            case ANY_OBJECT:
+                result = (T) new AnyObjectTO();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
new file mode 100644
index 0000000..f68b3f9
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity;
+
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.springframework.stereotype.Component;
+
+@Component
+public class JPAAnyUtilsFactory implements AnyUtilsFactory {
+
+    @Override
+    public AnyUtils getInstance(final AnyTypeKind anyTypeKind) {
+        return new JPAAnyUtils(anyTypeKind);
+    }
+
+    @Override
+    public AnyUtils getInstance(final String anyTypeKind) {
+        return new JPAAnyUtils(AnyTypeKind.valueOf(anyTypeKind));
+    }
+
+    @Override
+    public AnyUtils getInstance(final Any<?, ?, ?> any) {
+        AnyTypeKind type = null;
+        if (any instanceof User) {
+            type = AnyTypeKind.USER;
+        } else if (any instanceof Group) {
+            type = AnyTypeKind.GROUP;
+        } else if (any instanceof AnyObject) {
+            type = AnyTypeKind.ANY_OBJECT;
+        }
+
+        if (type == null) {
+            throw new IllegalArgumentException("Any type not supported: " + any.getClass().getName());
+        }
+
+        return new JPAAnyUtils(type);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAttributableUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAttributableUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAttributableUtils.java
deleted file mode 100644
index 2fe1ae9..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAttributableUtils.java
+++ /dev/null
@@ -1,862 +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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.ConfTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings({ "unchecked", "rawtypes" })
-public class JPAAttributableUtils implements AttributableUtils {
-
-    /**
-     * Logger.
-     */
-    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(AttributableUtils.class);
-
-    private final AttributableType type;
-
-    protected JPAAttributableUtils(final AttributableType type) {
-        this.type = type;
-    }
-
-    @Override
-    public AttributableType getType() {
-        return type;
-    }
-
-    @Override
-    public <T extends Attributable<?, ?, ?>> Class<T> attributableClass() {
-        Class result;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGroup.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMembership.class;
-                break;
-
-            case CONFIGURATION:
-                result = JPAConf.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUser.class;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainSchema> Class<T> plainSchemaClass() {
-        Class result;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGPlainSchema.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMPlainSchema.class;
-                break;
-
-            case CONFIGURATION:
-                result = JPACPlainSchema.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainSchema.class;
-                break;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainSchema> T newPlainSchema() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUPlainSchema();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGPlainSchema();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMPlainSchema();
-                break;
-
-            case CONFIGURATION:
-                result = (T) new JPACPlainSchema();
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttr> Class<T> plainAttrClass() {
-        Class result = null;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGPlainAttr.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMPlainAttr.class;
-                break;
-
-            case CONFIGURATION:
-                result = JPACPlainAttr.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttr.class;
-                break;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttr> T newPlainAttr() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUPlainAttr();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGPlainAttr();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMPlainAttr();
-                break;
-
-            case CONFIGURATION:
-                result = (T) new JPACPlainAttr();
-
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttrValue> Class<T> plainAttrValueClass() {
-        Class result;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGPlainAttrValue.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMPlainAttrValue.class;
-                break;
-
-            case CONFIGURATION:
-                result = JPACPlainAttrValue.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttrValue.class;
-                break;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttrValue> T newPlainAttrValue() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUPlainAttrValue();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGPlainAttrValue();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMPlainAttrValue();
-                break;
-
-            case CONFIGURATION:
-                result = (T) new JPACPlainAttrValue();
-                break;
-
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass() {
-        Class result;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGPlainAttrUniqueValue.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMPlainAttrUniqueValue.class;
-                break;
-
-            case CONFIGURATION:
-                result = JPACPlainAttrUniqueValue.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttrUniqueValue.class;
-                break;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends PlainAttrValue> T newPlainAttrUniqueValue() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUPlainAttrUniqueValue();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGPlainAttrUniqueValue();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMPlainAttrUniqueValue();
-                break;
-
-            case CONFIGURATION:
-                result = (T) new JPACPlainAttrUniqueValue();
-                break;
-
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AttrTemplate<PlainSchema>> Class<T> plainAttrTemplateClass() {
-        Class result;
-
-        switch (type) {
-            case GROUP:
-                result = JPAGPlainAttrTemplate.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMPlainAttrTemplate.class;
-                break;
-
-            case USER:
-            case CONFIGURATION:
-            default:
-                result = null;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends DerSchema> Class<T> derSchemaClass() {
-        Class result;
-
-        switch (type) {
-            case USER:
-                result = JPAUDerSchema.class;
-                break;
-
-            case GROUP:
-                result = JPAGDerSchema.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMDerSchema.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-                result = null;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends DerSchema> T newDerSchema() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUDerSchema();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGDerSchema();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMDerSchema();
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends DerAttr> Class<T> derAttrClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                result = JPAUDerAttr.class;
-                break;
-
-            case GROUP:
-                result = JPAGDerAttr.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMDerAttr.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends DerAttr> T newDerAttr() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUDerAttr();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGDerAttr();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMDerAttr();
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AttrTemplate<DerSchema>> Class<T> derAttrTemplateClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                break;
-
-            case GROUP:
-                result = JPAGDerAttrTemplate.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMDerAttrTemplate.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends VirSchema> Class<T> virSchemaClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                result = JPAUVirSchema.class;
-                break;
-
-            case GROUP:
-                result = JPAGVirSchema.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMVirSchema.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends VirSchema> T newVirSchema() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUVirSchema();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGVirSchema();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMVirSchema();
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends VirAttr> Class<T> virAttrClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                result = JPAUVirAttr.class;
-                break;
-
-            case GROUP:
-                result = JPAGVirAttr.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMVirAttr.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends VirAttr> T newVirAttr() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new JPAUVirAttr();
-                break;
-
-            case GROUP:
-                result = (T) new JPAGVirAttr();
-                break;
-
-            case MEMBERSHIP:
-                result = (T) new JPAMVirAttr();
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AttrTemplate<VirSchema>> Class<T> virAttrTemplateClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                break;
-
-            case GROUP:
-                result = JPAGVirAttrTemplate.class;
-                break;
-
-            case MEMBERSHIP:
-                result = JPAMVirAttrTemplate.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends MappingItem> T getAccountIdItem(final ExternalResource resource) {
-        T result = null;
-
-        if (resource != null) {
-            switch (type) {
-                case GROUP:
-                    if (resource.getGmapping() != null) {
-                        result = (T) resource.getGmapping().getAccountIdItem();
-                    }
-                    break;
-
-                case MEMBERSHIP:
-                case USER:
-                    if (resource.getUmapping() != null) {
-                        result = (T) resource.getUmapping().getAccountIdItem();
-                    }
-                    break;
-
-                default:
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public String getAccountLink(final ExternalResource resource) {
-        String result = null;
-
-        if (resource != null) {
-            switch (type) {
-                case USER:
-                    if (resource.getUmapping() != null) {
-                        result = resource.getUmapping().getAccountLink();
-                    }
-                    break;
-
-                case GROUP:
-                    if (resource.getGmapping() != null) {
-                        result = resource.getGmapping().getAccountLink();
-                    }
-                    break;
-
-                case MEMBERSHIP:
-                case CONFIGURATION:
-                default:
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends MappingItem> List<T> getMappingItems(
-            final ExternalResource resource, final MappingPurpose purpose) {
-
-        List<T> items = Collections.<T>emptyList();
-
-        if (resource != null) {
-            switch (type) {
-                case GROUP:
-                    if (resource.getGmapping() != null) {
-                        items = (List<T>) resource.getGmapping().getItems();
-                    }
-                    break;
-
-                case MEMBERSHIP:
-                case USER:
-                    if (resource.getUmapping() != null) {
-                        items = (List<T>) resource.getUmapping().getItems();
-                    }
-                    break;
-
-                default:
-            }
-        }
-
-        final List<T> result = new ArrayList<>();
-
-        switch (purpose) {
-            case SYNCHRONIZATION:
-                for (T item : items) {
-                    if (MappingPurpose.PROPAGATION != item.getPurpose()
-                            && MappingPurpose.NONE != item.getPurpose()) {
-
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case PROPAGATION:
-                for (T item : items) {
-                    if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
-                            && MappingPurpose.NONE != item.getPurpose()) {
-
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case BOTH:
-                for (T item : items) {
-                    if (MappingPurpose.NONE != item.getPurpose()) {
-                        result.add(item);
-                    }
-                }
-                break;
-
-            case NONE:
-                for (T item : items) {
-                    if (MappingPurpose.NONE == item.getPurpose()) {
-                        result.add(item);
-                    }
-                }
-                break;
-            default:
-                LOG.error("You requested not existing purpose {}", purpose);
-        }
-
-        return result;
-    }
-
-    @Override
-    public IntMappingType plainIntMappingType() {
-        IntMappingType result = null;
-
-        switch (type) {
-            case GROUP:
-                result = IntMappingType.GroupPlainSchema;
-                break;
-
-            case MEMBERSHIP:
-                result = IntMappingType.MembershipPlainSchema;
-                break;
-
-            case USER:
-                result = IntMappingType.UserPlainSchema;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public IntMappingType derIntMappingType() {
-        IntMappingType result = null;
-
-        switch (type) {
-            case GROUP:
-                result = IntMappingType.GroupDerivedSchema;
-                break;
-
-            case MEMBERSHIP:
-                result = IntMappingType.MembershipDerivedSchema;
-                break;
-
-            case USER:
-                result = IntMappingType.UserDerivedSchema;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public IntMappingType virIntMappingType() {
-        IntMappingType result = null;
-
-        switch (type) {
-            case GROUP:
-                result = IntMappingType.GroupVirtualSchema;
-                break;
-
-            case MEMBERSHIP:
-                result = IntMappingType.MembershipVirtualSchema;
-                break;
-
-            case USER:
-                result = IntMappingType.UserVirtualSchema;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends MappingItem> Class<T> mappingItemClass() {
-        Class result = null;
-
-        switch (type) {
-            case USER:
-                result = JPAUMappingItem.class;
-                break;
-
-            case GROUP:
-                result = JPAGMappingItem.class;
-                break;
-
-            case MEMBERSHIP:
-                result = AbstractMappingItem.class;
-                break;
-
-            case CONFIGURATION:
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AbstractAttributableTO> T newAttributableTO() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new UserTO();
-                break;
-            case GROUP:
-                result = (T) new GroupTO();
-                break;
-            case MEMBERSHIP:
-                result = (T) new MembershipTO();
-                break;
-            case CONFIGURATION:
-                result = (T) new ConfTO();
-                break;
-            default:
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AbstractSubjectTO> T newSubjectTO() {
-        T result = null;
-
-        switch (type) {
-            case USER:
-                result = (T) new UserTO();
-                break;
-            case GROUP:
-                result = (T) new GroupTO();
-                break;
-            case MEMBERSHIP:
-            case CONFIGURATION:
-            default:
-                break;
-        }
-
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
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 746bf48..3929496 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 org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -41,7 +42,7 @@ 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.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
new file mode 100644
index 0000000..0b9a31b
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
+
+@Entity
+@Table(name = JPADerSchema.TABLE)
+@Cacheable
+@SchemaNameCheck
+public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
+
+    private static final long serialVersionUID = -6173643493348674060L;
+
+    public static final String TABLE = "DerSchema";
+
+    @Id
+    private String name;
+
+    @Column(nullable = false)
+    private String expression;
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String key) {
+        this.name = key;
+    }
+
+    @Override
+    public String getExpression() {
+        return expression;
+    }
+
+    @Override
+    public void setExpression(final String expression) {
+        this.expression = expression;
+    }
+
+    @Override
+    public AttrSchemaType getType() {
+        return AttrSchemaType.String;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return Boolean.FALSE.toString().toLowerCase();
+    }
+
+    @Override
+    public boolean isMultivalue() {
+        return Boolean.TRUE;
+    }
+
+    @Override
+    public boolean isUniqueConstraint() {
+        return Boolean.FALSE;
+    }
+
+    @Override
+    public boolean isReadonly() {
+        return Boolean.FALSE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java
deleted file mode 100644
index 1f55348..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java
+++ /dev/null
@@ -1,77 +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;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-
-@Entity
-@Table(name = JPADynGroupMembership.TABLE)
-public class JPADynGroupMembership extends AbstractDynMembership implements DynGroupMembership {
-
-    private static final long serialVersionUID = -7336814163949640354L;
-
-    public static final String TABLE = "DynGroupMembership";
-
-    @Id
-    private Long id;
-
-    @OneToOne
-    private JPAGroup group;
-
-    @ManyToMany
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "dynGroupMembership_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "user_id"))
-    private List<JPAUser> users = new ArrayList<>();
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    protected List<JPAUser> internalGetUsers() {
-        return users;
-    }
-
-    @Override
-    public Group getGroup() {
-        return group;
-    }
-
-    @Override
-    public void setGroup(final Group role) {
-        checkType(role, JPAGroup.class);
-        this.group = (JPAGroup) role;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
deleted file mode 100644
index 4796abf..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
+++ /dev/null
@@ -1,76 +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;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
-import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-
-@Entity
-@Table(name = JPADynRoleMembership.TABLE)
-public class JPADynRoleMembership extends AbstractDynMembership implements DynRoleMembership {
-
-    private static final long serialVersionUID = -7336814163949640354L;
-
-    public static final String TABLE = "DynRoleMembership";
-
-    @Id
-    private Long id;
-
-    @OneToOne
-    private JPARole role;
-
-    @ManyToMany
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "dynRoleMembership_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "user_id"))
-    private List<JPAUser> users = new ArrayList<>();
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    protected List<JPAUser> internalGetUsers() {
-        return users;
-    }
-
-    @Override
-    public Role getRole() {
-        return role;
-    }
-
-    @Override
-    public void setRole(final Role role) {
-        checkType(role, JPARole.class);
-        this.role = (JPARole) role;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 048955b..92f9855 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
@@ -18,17 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
+import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
 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.DynGroupMembership;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 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.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.PushPolicy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Report;
@@ -36,37 +40,25 @@ import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.persistence.api.entity.ReportletConfInstance;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+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.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.Conf;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.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.AnyFilter;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
@@ -75,47 +67,32 @@ import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMapping;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirSchema;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+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.task.JPAAnyFilter;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
@@ -123,15 +100,13 @@ import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskExec;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMapping;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirSchema;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.springframework.stereotype.Component;
 
@@ -159,86 +134,56 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAUser();
         } else if (reference.equals(Group.class)) {
             result = (T) new JPAGroup();
-        } else if (reference.equals(Membership.class)) {
-            result = (T) new JPAMembership();
+        } else if (reference.equals(ARelationship.class)) {
+            result = (T) new JPAARelationship();
+        } else if (reference.equals(URelationship.class)) {
+            result = (T) new JPAURelationship();
+        } else if (reference.equals(AMembership.class)) {
+            result = (T) new JPAAMembership();
+        } else if (reference.equals(UMembership.class)) {
+            result = (T) new JPAUMembership();
         } else if (reference.equals(Conf.class)) {
             result = (T) new JPAConf();
+        } else if (reference.equals(AnyAbout.class)) {
+            result = (T) new JPAAnyAbout();
         } else if (reference.equals(Notification.class)) {
             result = (T) new JPANotification();
         } else if (reference.equals(ExternalResource.class)) {
             result = (T) new JPAExternalResource();
+        } else if (reference.equals(Provision.class)) {
+            result = (T) new JPAProvision();
         } else if (reference.equals(ConnInstance.class)) {
             result = (T) new JPAConnInstance();
-        } else if (reference.equals(UPlainSchema.class)) {
-            result = (T) new JPAUPlainSchema();
+        } else if (reference.equals(PlainSchema.class)) {
+            result = (T) new JPAPlainSchema();
         } else if (reference.equals(UPlainAttr.class)) {
             result = (T) new JPAUPlainAttr();
         } else if (reference.equals(UPlainAttrValue.class)) {
             result = (T) new JPAUPlainAttrValue();
         } else if (reference.equals(UPlainAttrUniqueValue.class)) {
             result = (T) new JPAUPlainAttrUniqueValue();
-        } else if (reference.equals(UDerSchema.class)) {
-            result = (T) new JPAUDerSchema();
+        } else if (reference.equals(DerSchema.class)) {
+            result = (T) new JPADerSchema();
         } else if (reference.equals(UDerAttr.class)) {
             result = (T) new JPAUDerAttr();
-        } else if (reference.equals(UVirSchema.class)) {
-            result = (T) new JPAUVirSchema();
+        } else if (reference.equals(VirSchema.class)) {
+            result = (T) new JPAVirSchema();
         } else if (reference.equals(UVirAttr.class)) {
             result = (T) new JPAUVirAttr();
-        } else if (reference.equals(UMapping.class)) {
-            result = (T) new JPAUMapping();
-        } else if (reference.equals(UMappingItem.class)) {
-            result = (T) new JPAUMappingItem();
-        } else if (reference.equals(GPlainSchema.class)) {
-            result = (T) new JPAGPlainSchema();
+        } else if (reference.equals(Mapping.class)) {
+            result = (T) new JPAMapping();
+        } else if (reference.equals(MappingItem.class)) {
+            result = (T) new JPAMappingItem();
         } else if (reference.equals(GPlainAttr.class)) {
             result = (T) new JPAGPlainAttr();
         } else if (reference.equals(GPlainAttrValue.class)) {
             result = (T) new JPAGPlainAttrValue();
         } else if (reference.equals(GPlainAttrUniqueValue.class)) {
             result = (T) new JPAGPlainAttrUniqueValue();
-        } else if (reference.equals(GPlainAttrTemplate.class)) {
-            result = (T) new JPAGPlainAttrTemplate();
-        } else if (reference.equals(GDerAttrTemplate.class)) {
-            result = (T) new JPAGDerAttrTemplate();
-        } else if (reference.equals(GVirAttrTemplate.class)) {
-            result = (T) new JPAGVirAttrTemplate();
-        } else if (reference.equals(GDerSchema.class)) {
-            result = (T) new JPAGDerSchema();
         } else if (reference.equals(GDerAttr.class)) {
             result = (T) new JPAGDerAttr();
-        } else if (reference.equals(GVirSchema.class)) {
-            result = (T) new JPAGVirSchema();
         } else if (reference.equals(GVirAttr.class)) {
             result = (T) new JPAGVirAttr();
-        } else if (reference.equals(GMapping.class)) {
-            result = (T) new JPAGMapping();
-        } else if (reference.equals(GMappingItem.class)) {
-            result = (T) new JPAGMappingItem();
-        } else if (reference.equals(MPlainSchema.class)) {
-            result = (T) new JPAMPlainSchema();
-        } else if (reference.equals(MPlainAttr.class)) {
-            result = (T) new JPAMPlainAttr();
-        } else if (reference.equals(MPlainAttrValue.class)) {
-            result = (T) new JPAMPlainAttrValue();
-        } else if (reference.equals(MPlainAttrUniqueValue.class)) {
-            result = (T) new JPAMPlainAttrUniqueValue();
-        } else if (reference.equals(MDerSchema.class)) {
-            result = (T) new JPAMDerSchema();
-        } else if (reference.equals(MDerAttr.class)) {
-            result = (T) new JPAMDerAttr();
-        } else if (reference.equals(MVirSchema.class)) {
-            result = (T) new JPAMVirSchema();
-        } else if (reference.equals(MVirAttr.class)) {
-            result = (T) new JPAMVirAttr();
-        } else if (reference.equals(MPlainAttrTemplate.class)) {
-            result = (T) new JPAMPlainAttrTemplate();
-        } else if (reference.equals(MDerAttrTemplate.class)) {
-            result = (T) new JPAMDerAttrTemplate();
-        } else if (reference.equals(MVirAttrTemplate.class)) {
-            result = (T) new JPAMVirAttrTemplate();
-        } else if (reference.equals(CPlainSchema.class)) {
-            result = (T) new JPACPlainSchema();
         } else if (reference.equals(CPlainAttr.class)) {
             result = (T) new JPACPlainAttr();
         } else if (reference.equals(CPlainAttrValue.class)) {
@@ -263,14 +208,20 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPASchedTask();
         } else if (reference.equals(TaskExec.class)) {
             result = (T) new JPATaskExec();
+        } else if (reference.equals(AnyFilter.class)) {
+            result = (T) new JPAAnyFilter();
+        } else if (reference.equals(AnyTemplate.class)) {
+            result = (T) new JPAAnyTemplate();
         } else if (reference.equals(SecurityQuestion.class)) {
             result = (T) new JPASecurityQuestion();
         } else if (reference.equals(Logger.class)) {
             result = (T) new JPALogger();
         } else if (reference.equals(DynRoleMembership.class)) {
             result = (T) new JPADynRoleMembership();
-        } else if (reference.equals(DynGroupMembership.class)) {
-            result = (T) new JPADynGroupMembership();
+        } else if (reference.equals(ADynGroupMembership.class)) {
+            result = (T) new JPAADynGroupMembership();
+        } else if (reference.equals(UDynGroupMembership.class)) {
+            result = (T) new JPAUDynGroupMembership();
         } else {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }


[29/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
[SYNCOPE-666] Initial commit, Travis CI builds disabled


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

Branch: refs/heads/SYNCOPE-666
Commit: 081d9a04ae66b9200ab9538ad64c927e8f121e1a
Parents: 4cd6f5d
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon May 25 16:50:15 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon May 25 16:50:15 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |   3 +-
 .../client/console/commons/AttrLayoutType.java  |  38 +-
 .../SortableAttributableProviderComparator.java |  20 +-
 .../commons/status/ConnObjectWrapper.java       |  12 +-
 .../console/commons/status/StatusBean.java      |  22 +-
 .../console/commons/status/StatusUtils.java     |  35 +-
 .../console/rest/AbstractAnyRestClient.java     |  47 +
 .../console/rest/AbstractSubjectRestClient.java |  48 -
 .../console/rest/ConfigurationRestClient.java   |   2 +-
 .../client/console/rest/GroupRestClient.java    |   8 +-
 .../client/console/rest/ResourceRestClient.java |  13 +-
 .../client/console/rest/SchemaRestClient.java   |  94 +-
 .../client/console/rest/UserRestClient.java     |   8 +-
 .../client/console/rest/WorkflowRestClient.java |   8 +-
 .../syncope/client/lib/SyncopeClient.java       |  20 +-
 .../lib/builders/AnyListQueryBuilder.java       |  61 ++
 .../lib/builders/AnySearchQueryBuilder.java     |  64 ++
 .../lib/builders/SubjectListQueryBuilder.java   |  61 --
 .../lib/builders/SubjectSearchQueryBuilder.java |  64 --
 .../syncope/common/lib/AnyOperations.java       | 375 ++++++++
 .../common/lib/AttributableOperations.java      | 509 -----------
 .../syncope/common/lib/CollectionUtils2.java    | 153 ----
 .../common/lib/mod/AbstractAttributableMod.java | 111 ---
 .../common/lib/mod/AbstractSubjectMod.java      |  66 --
 .../apache/syncope/common/lib/mod/AnyMod.java   | 135 +++
 .../syncope/common/lib/mod/AnyObjectMod.java    |  71 ++
 .../apache/syncope/common/lib/mod/GroupMod.java | 135 +--
 .../syncope/common/lib/mod/MembershipMod.java   |  46 -
 .../apache/syncope/common/lib/mod/UserMod.java  |  56 +-
 .../lib/report/AbstractAnyReportletConf.java    |  84 ++
 .../report/AbstractSubjectReportletConf.java    |  84 --
 .../common/lib/report/GroupReportletConf.java   |   2 +-
 .../common/lib/report/UserReportletConf.java    |   2 +-
 .../common/lib/search/SearchableFields.java     |  17 +-
 .../common/lib/to/AbstractAttributableTO.java   |  85 --
 .../common/lib/to/AbstractSubjectTO.java        |  63 --
 .../syncope/common/lib/to/AnyObjectTO.java      |  30 +
 .../org/apache/syncope/common/lib/to/AnyTO.java | 180 ++++
 .../apache/syncope/common/lib/to/ConfTO.java    |   2 +-
 .../apache/syncope/common/lib/to/GroupTO.java   |  72 +-
 .../apache/syncope/common/lib/to/MappingTO.java |  62 +-
 .../syncope/common/lib/to/MembershipTO.java     |  13 +-
 .../syncope/common/lib/to/NotificationTO.java   |  22 +-
 .../common/lib/to/PropagationTaskTO.java        |  43 +-
 .../syncope/common/lib/to/ProvisionTO.java      |  77 ++
 .../syncope/common/lib/to/PushTaskTO.java       |  21 +-
 .../syncope/common/lib/to/RelationshipTO.java   |  81 ++
 .../syncope/common/lib/to/ResourceTO.java       |  57 +-
 .../syncope/common/lib/to/SyncTaskTO.java       |  22 +-
 .../apache/syncope/common/lib/to/SyncopeTO.java |  30 +-
 .../apache/syncope/common/lib/to/UserTO.java    |  51 +-
 .../syncope/common/lib/types/AnyTypeKind.java   |  30 +
 .../common/lib/types/AttributableType.java      |  31 -
 .../syncope/common/lib/types/Entitlement.java   |  12 +
 .../common/lib/types/EntityViolationType.java   |  13 +-
 .../common/lib/types/IntMappingType.java        |  92 +-
 .../syncope/common/lib/types/SubjectType.java   |  34 -
 .../common/lib/types/SyncPolicySpec.java        |  59 +-
 .../common/lib/types/SyncPolicySpecItem.java    |  67 ++
 .../apache/syncope/common/lib/wrap/AnyKey.java  |  25 +
 .../syncope/common/lib/wrap/SubjectKey.java     |  25 -
 .../common/rest/api/beans/AnyListQuery.java     |  41 +
 .../common/rest/api/beans/AnySearchQuery.java   |  39 +
 .../common/rest/api/beans/SubjectListQuery.java |  41 -
 .../rest/api/beans/SubjectSearchQuery.java      |  39 -
 .../common/rest/api/service/GroupService.java   |   8 +-
 .../rest/api/service/ResourceService.java       |  27 +-
 .../common/rest/api/service/SchemaService.java  |  35 +-
 .../common/rest/api/service/UserService.java    |   8 +-
 .../rest/api/service/WorkflowService.java       |  14 +-
 .../syncope/core/logic/AbstractAnyLogic.java    |  84 ++
 .../core/logic/AbstractResourceAssociator.java  |   4 +-
 .../core/logic/AbstractSubjectLogic.java        |  84 --
 .../syncope/core/logic/AnyObjectLogic.java      | 326 +++++++
 .../syncope/core/logic/ConfigurationLogic.java  |   4 +-
 .../syncope/core/logic/ConnectorLogic.java      |  34 +-
 .../apache/syncope/core/logic/GroupLogic.java   |  28 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |  42 +-
 .../apache/syncope/core/logic/ReportLogic.java  |  15 +-
 .../syncope/core/logic/ResourceLogic.java       |  80 +-
 .../apache/syncope/core/logic/SchemaLogic.java  | 100 +--
 .../apache/syncope/core/logic/SyncopeLogic.java |  16 +-
 .../apache/syncope/core/logic/UserLogic.java    |  44 +-
 .../syncope/core/logic/UserWorkflowLogic.java   |   8 +-
 .../syncope/core/logic/WorkflowLogic.java       |  21 +
 .../core/logic/report/GroupReportlet.java       |  43 +-
 .../core/logic/report/UserReportlet.java        |  49 +-
 .../syncope/core/logic/NotificationTest.java    |  77 +-
 .../syncope/core/misc/ConnObjectUtils.java      | 381 ++++----
 .../apache/syncope/core/misc/MappingUtils.java  | 406 +++------
 .../syncope/core/misc/jexl/JexlUtils.java       |  38 +-
 .../core/misc/policy/PolicyEvaluator.java       |  16 +-
 .../core/misc/search/SearchCondVisitor.java     |  26 +-
 .../core/misc/security/PasswordGenerator.java   |   2 +-
 .../security/SyncopeAuthenticationProvider.java |  24 +-
 .../security/SyncopeUserDetailsService.java     |   6 +-
 .../misc/security/UnauthorizedException.java    |   6 +-
 .../misc/search/SearchCondConverterTest.java    |  10 +-
 .../core/persistence/api/dao/AnyDAO.java        |  66 ++
 .../core/persistence/api/dao/AnyObjectDAO.java  |  40 +
 .../core/persistence/api/dao/AnySearchDAO.java  |  83 ++
 .../persistence/api/dao/AnyTypeClassDAO.java    |  33 +
 .../core/persistence/api/dao/AnyTypeDAO.java    |  37 +
 .../persistence/api/dao/AttrTemplateDAO.java    |  34 -
 .../core/persistence/api/dao/DerAttrDAO.java    |  12 +-
 .../core/persistence/api/dao/DerSchemaDAO.java  |  11 +-
 .../api/dao/ExternalResourceDAO.java            |   6 +-
 .../core/persistence/api/dao/GroupDAO.java      |  53 +-
 .../core/persistence/api/dao/MembershipDAO.java |  40 -
 .../core/persistence/api/dao/PlainAttrDAO.java  |   8 +-
 .../persistence/api/dao/PlainSchemaDAO.java     |  11 +-
 .../core/persistence/api/dao/PolicyDAO.java     |   2 +-
 .../core/persistence/api/dao/SubjectDAO.java    |  44 -
 .../persistence/api/dao/SubjectSearchDAO.java   |  83 --
 .../core/persistence/api/dao/TaskDAO.java       |   2 +-
 .../core/persistence/api/dao/UserDAO.java       |  38 +-
 .../core/persistence/api/dao/VirAttrDAO.java    |  12 +-
 .../core/persistence/api/dao/VirSchemaDAO.java  |  11 +-
 .../persistence/api/dao/search/AnyCond.java     |  35 +
 .../persistence/api/dao/search/GroupCond.java   |  39 -
 .../api/dao/search/MembershipCond.java          |  39 +
 .../api/dao/search/RelationshipCond.java        |  39 +
 .../persistence/api/dao/search/SearchCond.java  |  66 +-
 .../persistence/api/dao/search/SubjectCond.java |  35 -
 .../persistence/api/entity/AccountPolicy.java   |   1 +
 .../core/persistence/api/entity/Any.java        |  80 ++
 .../core/persistence/api/entity/AnyAbout.java   |  34 +
 .../core/persistence/api/entity/AnyType.java    |  37 +
 .../persistence/api/entity/AnyTypeClass.java    |  44 +
 .../core/persistence/api/entity/AnyUtils.java   |  68 ++
 .../persistence/api/entity/AnyUtilsFactory.java |  30 +
 .../core/persistence/api/entity/Attr.java       |   6 +-
 .../persistence/api/entity/AttrTemplate.java    |  32 -
 .../persistence/api/entity/Attributable.java    |  48 -
 .../api/entity/AttributableUtils.java           |  89 --
 .../api/entity/AttributableUtilsFactory.java    |  33 -
 .../persistence/api/entity/ConnInstance.java    |   1 +
 .../core/persistence/api/entity/DerAttr.java    |   4 +-
 .../api/entity/DynGroupMembership.java          |   4 +-
 .../persistence/api/entity/DynMembership.java   |   9 +-
 .../api/entity/DynRoleMembership.java           |  26 -
 .../api/entity/ExternalResource.java            | 111 ---
 .../core/persistence/api/entity/Mapping.java    |  42 -
 .../persistence/api/entity/MappingItem.java     |  57 --
 .../core/persistence/api/entity/Membership.java |  25 +
 .../persistence/api/entity/Notification.java    |  45 +-
 .../core/persistence/api/entity/PlainAttr.java  |  11 +-
 .../persistence/api/entity/PlainAttrValue.java  |   4 +-
 .../persistence/api/entity/Relationship.java    |  30 +
 .../core/persistence/api/entity/Role.java       |   1 +
 .../core/persistence/api/entity/Subject.java    |  36 -
 .../core/persistence/api/entity/VirAttr.java    |   6 +-
 .../api/entity/anyobject/ADerAttr.java          |  24 +
 .../entity/anyobject/ADynGroupMembership.java   |  25 +
 .../api/entity/anyobject/AMembership.java       |  25 +
 .../api/entity/anyobject/APlainAttr.java        |  32 +
 .../entity/anyobject/APlainAttrUniqueValue.java |  28 +
 .../api/entity/anyobject/APlainAttrValue.java   |  28 +
 .../api/entity/anyobject/ARelationship.java     |  25 +
 .../api/entity/anyobject/AVirAttr.java          |  25 +
 .../api/entity/anyobject/AnyObject.java         |  42 +
 .../persistence/api/entity/conf/CPlainAttr.java |   9 +-
 .../api/entity/conf/CPlainAttrUniqueValue.java  |   3 -
 .../api/entity/conf/CPlainSchema.java           |  25 -
 .../core/persistence/api/entity/conf/Conf.java  |   8 +-
 .../persistence/api/entity/group/GDerAttr.java  |  11 +-
 .../api/entity/group/GDerAttrTemplate.java      |  25 -
 .../api/entity/group/GDerSchema.java            |  25 -
 .../persistence/api/entity/group/GMapping.java  |  25 -
 .../api/entity/group/GMappingItem.java          |  29 -
 .../api/entity/group/GPlainAttr.java            |  12 +-
 .../api/entity/group/GPlainAttrTemplate.java    |  25 -
 .../api/entity/group/GPlainAttrUniqueValue.java |   3 -
 .../api/entity/group/GPlainSchema.java          |  25 -
 .../persistence/api/entity/group/GVirAttr.java  |  11 +-
 .../api/entity/group/GVirAttrTemplate.java      |  25 -
 .../api/entity/group/GVirSchema.java            |  25 -
 .../persistence/api/entity/group/Group.java     |  54 +-
 .../api/entity/group/TypeExtension.java         |  41 +
 .../api/entity/membership/MDerAttr.java         |  34 -
 .../api/entity/membership/MDerAttrTemplate.java |  25 -
 .../api/entity/membership/MDerSchema.java       |  25 -
 .../api/entity/membership/MPlainAttr.java       |  42 -
 .../entity/membership/MPlainAttrTemplate.java   |  25 -
 .../membership/MPlainAttrUniqueValue.java       |  31 -
 .../api/entity/membership/MPlainAttrValue.java  |  28 -
 .../api/entity/membership/MPlainSchema.java     |  25 -
 .../api/entity/membership/MVirAttr.java         |  34 -
 .../api/entity/membership/MVirAttrTemplate.java |  25 -
 .../api/entity/membership/MVirSchema.java       |  25 -
 .../api/entity/membership/Membership.java       |  53 --
 .../api/entity/resource/ExternalResource.java   | 106 +++
 .../api/entity/resource/Mapping.java            |  43 +
 .../api/entity/resource/MappingItem.java        |  59 ++
 .../api/entity/resource/Provision.java          |  49 +
 .../persistence/api/entity/task/AnyFilter.java  |  37 +
 .../api/entity/task/AnyTemplate.java            |  38 +
 .../api/entity/task/PropagationTask.java        |  40 +-
 .../api/entity/task/ProvisioningTask.java       |  26 +-
 .../persistence/api/entity/task/PushTask.java   |  11 +-
 .../persistence/api/entity/task/SyncTask.java   |  16 +-
 .../api/entity/user/DynRoleMembership.java      |  29 +
 .../persistence/api/entity/user/UDerAttr.java   |   8 +-
 .../persistence/api/entity/user/UDerSchema.java |  25 -
 .../api/entity/user/UDynGroupMembership.java    |  25 +
 .../api/entity/user/UDynMembership.java         |  25 +
 .../persistence/api/entity/user/UMapping.java   |  28 -
 .../api/entity/user/UMappingItem.java           |  29 -
 .../api/entity/user/UMembership.java            |  25 +
 .../persistence/api/entity/user/UPlainAttr.java |   8 +-
 .../api/entity/user/UPlainAttrUniqueValue.java  |   3 -
 .../api/entity/user/UPlainSchema.java           |  25 -
 .../api/entity/user/URelationship.java          |  26 +
 .../persistence/api/entity/user/UVirAttr.java   |   8 +-
 .../persistence/api/entity/user/UVirSchema.java |  25 -
 .../core/persistence/api/entity/user/User.java  | 126 ++-
 .../jpa/content/XMLContentExporter.java         |  21 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     | 434 +++++++++
 .../core/persistence/jpa/dao/AbstractDAO.java   |   3 -
 .../persistence/jpa/dao/AbstractSubjectDAO.java | 361 --------
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    | 149 ++++
 .../persistence/jpa/dao/JPAAnySearchDAO.java    | 811 +++++++++++++++++
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |  58 ++
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |  83 ++
 .../persistence/jpa/dao/JPAAttrTemplateDAO.java | 107 ---
 .../core/persistence/jpa/dao/JPAConfDAO.java    |  31 +-
 .../persistence/jpa/dao/JPAConnInstanceDAO.java |   2 +-
 .../core/persistence/jpa/dao/JPADerAttrDAO.java |  26 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |  84 +-
 .../jpa/dao/JPAExternalResourceDAO.java         |  82 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   | 349 ++------
 .../persistence/jpa/dao/JPAMembershipDAO.java   | 104 ---
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    |  22 +-
 .../jpa/dao/JPAPlainAttrValueDAO.java           |  18 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |  95 +-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java  |   2 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |  16 +-
 .../jpa/dao/JPASubjectSearchDAO.java            | 778 ----------------
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   2 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    | 222 +----
 .../core/persistence/jpa/dao/JPAVirAttrDAO.java |  26 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |  83 +-
 .../core/persistence/jpa/dao/SearchSupport.java |  31 +-
 .../persistence/jpa/entity/AbstractAny.java     | 149 ++++
 .../jpa/entity/AbstractAttrTemplate.java        |  28 -
 .../jpa/entity/AbstractAttributable.java        |  68 --
 .../persistence/jpa/entity/AbstractDerAttr.java |  24 +-
 .../jpa/entity/AbstractDerAttrTemplate.java     |  41 -
 .../jpa/entity/AbstractDerSchema.java           |  85 --
 .../jpa/entity/AbstractDynMembership.java       |  26 +-
 .../persistence/jpa/entity/AbstractMapping.java |  78 --
 .../jpa/entity/AbstractMappingItem.java         | 190 ----
 .../jpa/entity/AbstractPlainAttr.java           |  49 +-
 .../jpa/entity/AbstractPlainAttrTemplate.java   |  27 -
 .../jpa/entity/AbstractPlainSchema.java         | 272 ------
 .../persistence/jpa/entity/AbstractSubject.java |  85 --
 .../persistence/jpa/entity/AbstractVirAttr.java |  27 +-
 .../jpa/entity/AbstractVirAttrTemplate.java     |  41 -
 .../jpa/entity/AbstractVirSchema.java           |  89 --
 .../jpa/entity/JPAAccountPolicy.java            |   7 +-
 .../persistence/jpa/entity/JPAAnyAbout.java     |  89 ++
 .../core/persistence/jpa/entity/JPAAnyType.java |  97 ++
 .../persistence/jpa/entity/JPAAnyTypeClass.java | 131 +++
 .../persistence/jpa/entity/JPAAnyUtils.java     | 488 ++++++++++
 .../jpa/entity/JPAAnyUtilsFactory.java          |  61 ++
 .../jpa/entity/JPAAttributableUtils.java        | 862 ------------------
 .../persistence/jpa/entity/JPAConnInstance.java |   3 +-
 .../persistence/jpa/entity/JPADerSchema.java    |  91 ++
 .../jpa/entity/JPADynGroupMembership.java       |  77 --
 .../jpa/entity/JPADynRoleMembership.java        |  76 --
 .../jpa/entity/JPAEntityFactory.java            | 169 ++--
 .../jpa/entity/JPAExternalResource.java         | 428 ---------
 .../persistence/jpa/entity/JPANotification.java |  64 +-
 .../persistence/jpa/entity/JPAPlainSchema.java  | 276 ++++++
 .../core/persistence/jpa/entity/JPARole.java    |   3 +-
 .../persistence/jpa/entity/JPAVirSchema.java    |  95 ++
 .../jpa/entity/JPAttributableUtilsFactory.java  |  81 --
 .../jpa/entity/anyobject/JPAADerAttr.java       |  50 ++
 .../anyobject/JPAADynGroupMembership.java       |  89 ++
 .../jpa/entity/anyobject/JPAAMembership.java    |  77 ++
 .../jpa/entity/anyobject/JPAAPlainAttr.java     | 105 +++
 .../anyobject/JPAAPlainAttrUniqueValue.java     |  78 ++
 .../entity/anyobject/JPAAPlainAttrValue.java    |  64 ++
 .../jpa/entity/anyobject/JPAARelationship.java  |  76 ++
 .../jpa/entity/anyobject/JPAAVirAttr.java       |  50 ++
 .../jpa/entity/anyobject/JPAAnyObject.java      | 243 +++++
 .../jpa/entity/conf/JPACPlainAttr.java          |  40 +-
 .../entity/conf/JPACPlainAttrUniqueValue.java   |  10 +-
 .../jpa/entity/conf/JPACPlainSchema.java        |  36 -
 .../persistence/jpa/entity/conf/JPAConf.java    | 123 ++-
 .../jpa/entity/group/JPAGDerAttr.java           |  36 +-
 .../jpa/entity/group/JPAGDerAttrTemplate.java   |  66 --
 .../jpa/entity/group/JPAGDerSchema.java         |  34 -
 .../jpa/entity/group/JPAGMapping.java           | 103 ---
 .../jpa/entity/group/JPAGMappingItem.java       |  58 --
 .../jpa/entity/group/JPAGPlainAttr.java         |  45 +-
 .../jpa/entity/group/JPAGPlainAttrTemplate.java |  75 --
 .../entity/group/JPAGPlainAttrUniqueValue.java  |  10 +-
 .../jpa/entity/group/JPAGPlainSchema.java       |  36 -
 .../jpa/entity/group/JPAGVirAttr.java           |  36 +-
 .../jpa/entity/group/JPAGVirAttrTemplate.java   |  66 --
 .../jpa/entity/group/JPAGVirSchema.java         |  36 -
 .../persistence/jpa/entity/group/JPAGroup.java  | 230 +++--
 .../jpa/entity/group/JPATypeExtension.java      | 108 +++
 .../jpa/entity/membership/JPAMDerAttr.java      |  82 --
 .../entity/membership/JPAMDerAttrTemplate.java  |  67 --
 .../jpa/entity/membership/JPAMDerSchema.java    |  34 -
 .../jpa/entity/membership/JPAMPlainAttr.java    | 141 ---
 .../membership/JPAMPlainAttrTemplate.java       |  77 --
 .../membership/JPAMPlainAttrUniqueValue.java    |  78 --
 .../entity/membership/JPAMPlainAttrValue.java   |  64 --
 .../jpa/entity/membership/JPAMPlainSchema.java  |  36 -
 .../jpa/entity/membership/JPAMVirAttr.java      |  81 --
 .../entity/membership/JPAMVirAttrTemplate.java  |  67 --
 .../jpa/entity/membership/JPAMVirSchema.java    |  36 -
 .../jpa/entity/membership/JPAMembership.java    | 220 -----
 .../entity/resource/JPAExternalResource.java    | 394 ++++++++
 .../jpa/entity/resource/JPAMapping.java         | 142 +++
 .../jpa/entity/resource/JPAMappingItem.java     | 217 +++++
 .../jpa/entity/resource/JPAProvision.java       | 133 +++
 .../entity/task/AbstractProvisioningTask.java   |   4 +-
 .../jpa/entity/task/JPAAnyFilter.java           |  91 ++
 .../jpa/entity/task/JPAAnyTemplate.java         | 102 +++
 .../jpa/entity/task/JPANotificationTask.java    |   2 +-
 .../jpa/entity/task/JPAPropagationTask.java     |  50 +-
 .../jpa/entity/task/JPAPushTask.java            |  37 +-
 .../jpa/entity/task/JPASyncTask.java            |  56 +-
 .../jpa/entity/user/AbstractUDynMembership.java |  50 ++
 .../jpa/entity/user/JPADynRoleMembership.java   |  76 ++
 .../jpa/entity/user/JPAUDerAttr.java            |  21 +-
 .../jpa/entity/user/JPAUDerSchema.java          |  34 -
 .../jpa/entity/user/JPAUDynGroupMembership.java |  76 ++
 .../jpa/entity/user/JPAUMapping.java            | 125 ---
 .../jpa/entity/user/JPAUMappingItem.java        |  58 --
 .../jpa/entity/user/JPAUMembership.java         |  77 ++
 .../jpa/entity/user/JPAUPlainAttr.java          |  40 +-
 .../entity/user/JPAUPlainAttrUniqueValue.java   |  10 +-
 .../jpa/entity/user/JPAUPlainSchema.java        |  36 -
 .../jpa/entity/user/JPAURelationship.java       |  78 ++
 .../jpa/entity/user/JPAUVirAttr.java            |  21 +-
 .../jpa/entity/user/JPAUVirSchema.java          |  36 -
 .../persistence/jpa/entity/user/JPAUser.java    | 192 ++--
 .../entity/EntityValidationListener.java        |   6 +-
 .../entity/ExternalResourceValidator.java       |  41 +-
 .../entity/PlainAttrValueValidator.java         |  13 +-
 .../validation/entity/SchemaNameValidator.java  |  72 +-
 .../jpa/validation/entity/UserValidator.java    |   2 +-
 .../src/main/resources/META-INF/spring-orm.xml  | 168 ++--
 .../src/main/resources/content.xml              |  71 +-
 .../src/main/resources/indexes.xml              |  15 +-
 .../src/main/resources/views.xml                | 185 +++-
 .../core/persistence/jpa/AbstractTest.java      |   4 +-
 .../persistence/jpa/DummyConnectorRegistry.java |   2 +-
 .../persistence/jpa/entity/AnySearchTest.java   | 500 +++++++++++
 .../core/persistence/jpa/entity/AttrTest.java   |  43 +-
 .../core/persistence/jpa/entity/ConfTest.java   |  24 +-
 .../persistence/jpa/entity/DerAttrTest.java     | 103 +--
 .../persistence/jpa/entity/DerSchemaTest.java   |  27 +-
 .../persistence/jpa/entity/MembershipTest.java  |  84 --
 .../jpa/entity/NotificationTest.java            |  27 +-
 .../persistence/jpa/entity/PlainSchemaTest.java |  48 +-
 .../core/persistence/jpa/entity/PolicyTest.java |  25 +-
 .../persistence/jpa/entity/ResourceTest.java    | 166 ++--
 .../jpa/entity/SubjectSearchTest.java           | 483 ----------
 .../core/persistence/jpa/entity/TaskTest.java   |  10 +-
 .../persistence/jpa/entity/VirAttrTest.java     |  38 +-
 .../persistence/jpa/entity/VirSchemaTest.java   |  27 +-
 .../jpa/relationship/AnySearchTest.java         | 115 +++
 .../persistence/jpa/relationship/AttrTest.java  |  79 +-
 .../jpa/relationship/ConnInstanceTest.java      |   2 +-
 .../jpa/relationship/DerSchemaTest.java         |   9 +-
 .../persistence/jpa/relationship/GroupTest.java |  42 +-
 .../jpa/relationship/MembershipTest.java        |  81 --
 .../jpa/relationship/PlainSchemaTest.java       |  55 +-
 .../jpa/relationship/ResourceTest.java          |  84 +-
 .../persistence/jpa/relationship/RoleTest.java  |  21 +-
 .../jpa/relationship/SubjectSearchTest.java     | 115 ---
 .../persistence/jpa/relationship/TaskTest.java  |  14 +-
 .../persistence/jpa/relationship/UserTest.java  |   7 +-
 .../src/test/resources/content.xml              | 889 ++++++++++---------
 .../api/AnyObjectProvisioningManager.java       |  34 +
 .../core/provisioning/api/AnyTransformer.java   |  33 +
 .../api/AttributableTransformer.java            |  33 -
 .../core/provisioning/api/Connector.java        |   2 +-
 .../core/provisioning/api/ConnectorFactory.java |   2 +-
 .../provisioning/api/ConnectorRegistry.java     |   2 +-
 .../api/GroupProvisioningManager.java           |   2 +-
 .../provisioning/api/ProvisioningManager.java   |  18 +-
 .../api/UserProvisioningManager.java            |   4 +-
 .../provisioning/api/cache/VirAttrCache.java    |  20 +-
 .../provisioning/api/cache/VirAttrCacheKey.java |  11 +-
 .../api/data/AnyObjectDataBinder.java           |  35 +
 .../api/data/ResourceDataBinder.java            |   2 +-
 .../provisioning/api/data/SchemaDataBinder.java |   5 +-
 .../api/propagation/PropagationManager.java     |  25 +-
 .../api/sync/AnyObjectPushResultHandler.java    |  23 +
 .../api/sync/AnyObjectSyncResultHandler.java    |  23 +
 .../api/sync/IgnoreProvisionException.java      |   2 +-
 .../api/sync/ProvisioningResult.java            |  11 +-
 .../core/provisioning/api/sync/PushActions.java | 100 +--
 .../core/provisioning/api/sync/SyncActions.java |  64 +-
 .../api/sync/SyncopePushResultHandler.java      |   2 +-
 .../provisioning/java/ConnectorFacadeProxy.java |   4 +-
 .../provisioning/java/ConnectorManager.java     |   2 +-
 .../java/DefaultAnyTransformer.java             |  40 +
 .../java/DefaultAttributableTransformer.java    |  39 -
 .../java/DefaultGroupProvisioningManager.java   |   6 +-
 .../java/DefaultUserProvisioningManager.java    |  27 +-
 .../core/provisioning/java/VirAttrHandler.java  | 198 ++---
 .../java/cache/DisabledVirAttrCache.java        |   9 +-
 .../java/cache/MemoryVirAttrCache.java          |  13 +-
 .../java/data/AbstractAnyDataBinder.java        | 663 ++++++++++++++
 .../data/AbstractAttributableDataBinder.java    | 805 -----------------
 .../java/data/ConfigurationDataBinderImpl.java  |  58 +-
 .../java/data/GroupDataBinderImpl.java          | 174 ++--
 .../java/data/NotificationDataBinderImpl.java   |  38 +-
 .../java/data/PolicyDataBinderImpl.java         |   2 +-
 .../java/data/ResourceDataBinderImpl.java       | 117 +--
 .../java/data/RoleDataBinderImpl.java           |   4 +-
 .../java/data/SchemaDataBinderImpl.java         |  26 +-
 .../java/data/TaskDataBinderImpl.java           | 117 ++-
 .../java/data/UserDataBinderImpl.java           | 156 +---
 .../notification/NotificationManagerImpl.java   | 109 +--
 .../AbstractPropagationTaskExecutor.java        |  89 +-
 .../DBPasswordPropagationActions.java           |   8 +-
 .../LDAPMembershipPropagationActions.java       |  20 +-
 .../LDAPPasswordPropagationActions.java         |   6 +-
 .../propagation/PropagationManagerImpl.java     | 214 ++---
 .../java/sync/AbstractProvisioningJob.java      | 123 ++-
 .../java/sync/AbstractPushResultHandler.java    | 172 ++--
 .../java/sync/AbstractSyncResultHandler.java    | 244 ++---
 .../java/sync/AbstractSyncopeResultHandler.java |  27 +-
 .../sync/AnyObjectPushResultHandlerImpl.java    | 157 ++++
 .../sync/AnyObjectSyncResultHandlerImpl.java    | 132 +++
 .../java/sync/DBPasswordSyncActions.java        |  30 +-
 .../java/sync/DefaultPushActions.java           |  34 +-
 .../java/sync/DefaultSyncActions.java           |  42 +-
 .../java/sync/GroupPushResultHandlerImpl.java   |  70 +-
 .../java/sync/GroupSyncResultHandlerImpl.java   |  71 +-
 .../java/sync/LDAPMembershipSyncActions.java    |  63 +-
 .../java/sync/LDAPPasswordSyncActions.java      |  10 +-
 .../provisioning/java/sync/PushJobImpl.java     | 109 +--
 .../provisioning/java/sync/SyncJobImpl.java     | 115 +--
 .../core/provisioning/java/sync/SyncUtils.java  | 194 ++--
 .../java/sync/UserPushResultHandlerImpl.java    |  71 +-
 .../java/sync/UserSyncResultHandlerImpl.java    |  43 +-
 .../provisioning/java/ConnectorManagerTest.java |   4 +-
 .../java/data/ResourceDataBinderTest.java       |  39 +-
 .../core/rest/cxf/service/GroupServiceImpl.java |   8 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |  33 +-
 .../rest/cxf/service/SchemaServiceImpl.java     |  27 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |   8 +-
 .../rest/cxf/service/WorkflowServiceImpl.java   |  20 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |   2 +-
 .../workflow/activiti/SyncopeUserQueryImpl.java |   9 +-
 .../workflow/api/AnyObjectWorkflowAdapter.java  |  61 ++
 .../core/workflow/api/WorkflowAdapter.java      |   8 +-
 .../java/AbstractGroupWorkflowAdapter.java      |   4 +-
 .../java/AbstractUserWorkflowAdapter.java       |  14 +-
 .../client/console/panels/CamelRoutePanel.java  |  71 +-
 .../console/rest/CamelRouteRestClient.java      |  19 +-
 .../syncope/common/lib/to/CamelRouteTO.java     |  14 +-
 .../syncope/core/logic/CamelRouteLogic.java     |   6 +-
 .../core/logic/init/CamelRouteLoader.java       |  19 +-
 .../core/persistence/api/dao/CamelRouteDAO.java |   4 +-
 .../core/persistence/api/entity/CamelRoute.java |  11 +-
 .../persistence/jpa/dao/JPACamelRouteDAO.java   |   8 +-
 .../persistence/jpa/entity/JPACamelRoute.java   |  12 +-
 .../camel/CamelUserProvisioningManager.java     |  11 +-
 .../camel/processor/GroupDeleteProcessor.java   |   2 +-
 .../processor/GroupDeprovisionProcessor.java    |   2 +-
 .../camel/processor/UserCreateProcessor.java    |   1 -
 .../processor/UserDeprovisionProcessor.java     |   2 +-
 .../camel/processor/UserUpdateProcessor.java    |  19 +-
 .../rest/api/service/CamelRouteService.java     |   4 +-
 .../rest/cxf/service/CamelRouteServiceImpl.java |   6 +-
 .../DoubleValueAttributableTransformer.java     |  12 +-
 .../fit/core/reference/TestSyncActions.java     |  10 +-
 .../fit/core/reference/AbstractITCase.java      |   7 +-
 .../core/reference/AuthenticationITCase.java    |  11 +-
 .../fit/core/reference/CamelRouteITCase.java    |   9 +-
 .../fit/core/reference/ConfigurationITCase.java |  11 +-
 .../fit/core/reference/ConnectorITCase.java     |  14 +-
 .../fit/core/reference/DerSchemaITCase.java     |  35 +-
 .../core/reference/ExceptionMapperITCase.java   |   3 +-
 .../syncope/fit/core/reference/GroupITCase.java |  69 +-
 .../fit/core/reference/LoggerITCase.java        |   6 +-
 .../fit/core/reference/NotificationITCase.java  |   6 +-
 .../core/reference/NotificationTaskITCase.java  |   6 +-
 .../fit/core/reference/PlainSchemaITCase.java   |  63 +-
 .../fit/core/reference/PolicyITCase.java        |  11 +-
 .../fit/core/reference/PushTaskITCase.java      |  86 +-
 .../fit/core/reference/ResourceITCase.java      | 171 ++--
 .../fit/core/reference/SearchITCase.java        |   6 +-
 .../fit/core/reference/SyncTaskITCase.java      |  39 +-
 .../syncope/fit/core/reference/UserITCase.java  | 268 ++----
 .../fit/core/reference/UserSelfITCase.java      |  23 +-
 .../fit/core/reference/UserWorkflowITCase.java  |  10 +-
 .../fit/core/reference/VirAttrITCase.java       | 311 +------
 .../fit/core/reference/VirSchemaITCase.java     |  24 +-
 .../fit/core/reference/WorkflowITCase.java      |  14 +-
 pom.xml                                         |   2 +-
 502 files changed, 16231 insertions(+), 17382 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 0e6f5c4..e17fd2c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ jdk:
 # default install is mvn install --quiet -DskipTests=true
 install: mvn --show-version --quiet -P all,skipTests
 #invoker.streamLogs: we cannot access to log files through Travis web ui, so display everything in the console
-script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
+#script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
+script: mvn --show-version --quiet -PskipTests -Dinvoker.streamLogs=true
 notifications:
   webhooks: http://rovere.tirasa.net/cgi-bin/travis.cgi

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/commons/AttrLayoutType.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttrLayoutType.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttrLayoutType.java
index 26764b4..9aefe4c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttrLayoutType.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttrLayoutType.java
@@ -20,27 +20,25 @@ package org.apache.syncope.client.console.commons;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 public enum AttrLayoutType {
 
-    ADMIN_USER("admin.user.layout", Mode.ADMIN, AttributableType.USER),
-    SELF_USER("self.user.layout", Mode.SELF, AttributableType.USER),
-    ADMIN_GROUP("admin.group.layout", Mode.ADMIN, AttributableType.GROUP),
-    SELF_GROUP("self.group.layout", Mode.SELF, AttributableType.GROUP),
-    ADMIN_MEMBERSHIP("admin.membership.layout", Mode.ADMIN, AttributableType.MEMBERSHIP),
-    SELF_MEMBERSHIP("self.membership.layout", Mode.SELF, AttributableType.MEMBERSHIP);
+    ADMIN_USER("admin.user.layout", Mode.ADMIN, AnyTypeKind.USER),
+    SELF_USER("self.user.layout", Mode.SELF, AnyTypeKind.USER),
+    ADMIN_GROUP("admin.group.layout", Mode.ADMIN, AnyTypeKind.GROUP),
+    SELF_GROUP("self.group.layout", Mode.SELF, AnyTypeKind.GROUP);
 
     private final String confKey;
 
     private final Mode mode;
 
-    private final AttributableType attrType;
+    private final AnyTypeKind anyTypeKind;
 
-    AttrLayoutType(final String confKey, final Mode mode, final AttributableType attrType) {
+    AttrLayoutType(final String confKey, final Mode mode, final AnyTypeKind anyTypeKind) {
         this.confKey = confKey;
         this.mode = mode;
-        this.attrType = attrType;
+        this.anyTypeKind = anyTypeKind;
     }
 
     public String getConfKey() {
@@ -51,12 +49,12 @@ public enum AttrLayoutType {
         return mode;
     }
 
-    public AttributableType getAttrType() {
-        return attrType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
     public static List<String> confKeys() {
-        List<String> confKeys = new ArrayList<String>();
+        List<String> confKeys = new ArrayList<>();
         for (AttrLayoutType value : values()) {
             confKeys.add(value.getConfKey());
         }
@@ -64,18 +62,14 @@ public enum AttrLayoutType {
         return confKeys;
     }
 
-    public static AttrLayoutType valueOf(final Mode mode, final AttributableType attrType) {
+    public static AttrLayoutType valueOf(final Mode mode, final AnyTypeKind anyTypeKind) {
         AttrLayoutType result = null;
         if (mode == Mode.ADMIN) {
-            switch (attrType) {
+            switch (anyTypeKind) {
                 case USER:
                     result = ADMIN_USER;
                     break;
 
-                case MEMBERSHIP:
-                    result = ADMIN_MEMBERSHIP;
-                    break;
-
                 case GROUP:
                     result = ADMIN_GROUP;
                     break;
@@ -83,15 +77,11 @@ public enum AttrLayoutType {
                 default:
             }
         } else if (mode == Mode.SELF) {
-            switch (attrType) {
+            switch (anyTypeKind) {
                 case USER:
                     result = SELF_USER;
                     break;
 
-                case MEMBERSHIP:
-                    result = SELF_MEMBERSHIP;
-                    break;
-
                 case GROUP:
                     result = SELF_GROUP;
                     break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java
index 77fb552..78b91ef 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java
@@ -23,30 +23,30 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
 import org.apache.wicket.model.AbstractReadOnlyModel;
 
-public class SortableAttributableProviderComparator extends SortableDataProviderComparator<AbstractAttributableTO> {
+public class SortableAttributableProviderComparator extends SortableDataProviderComparator<AnyTO> {
 
     private static final long serialVersionUID = 1775967163571699258L;
 
     private static final Set<String> INLINE_PROPS = new HashSet<>(Arrays.asList(
             new String[] { "key", "status", "token", "username" }));
 
-    public SortableAttributableProviderComparator(final SortableDataProvider<AbstractAttributableTO, String> provider) {
+    public SortableAttributableProviderComparator(final SortableDataProvider<AnyTO, String> provider) {
         super(provider);
     }
 
     @Override
-    public int compare(final AbstractAttributableTO attributable1, final AbstractAttributableTO attributable2) {
+    public int compare(final AnyTO any1, final AnyTO any2) {
         if (INLINE_PROPS.contains(provider.getSort().getProperty())) {
-            return super.compare(attributable1, attributable2);
+            return super.compare(any1, any2);
         }
 
-        return super.compare(new AttrModel(attributable1), new AttrModel(attributable2));
+        return super.compare(new AttrModel(any1), new AttrModel(any2));
     }
 
     @SuppressWarnings("rawtypes")
@@ -60,12 +60,12 @@ public class SortableAttributableProviderComparator extends SortableDataProvider
 
         private final Map<String, AttrTO> virAttrs;
 
-        public AttrModel(final AbstractAttributableTO attributableTO) {
+        public AttrModel(final AnyTO anyTO) {
             super();
 
-            this.attrs = attributableTO.getPlainAttrMap();
-            this.derAttrs = attributableTO.getDerAttrMap();
-            this.virAttrs = attributableTO.getVirAttrMap();
+            this.attrs = anyTO.getPlainAttrMap();
+            this.derAttrs = anyTO.getDerAttrMap();
+            this.virAttrs = anyTO.getVirAttrMap();
         }
 
         /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/commons/status/ConnObjectWrapper.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/ConnObjectWrapper.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/ConnObjectWrapper.java
index be038db..c66a825 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/ConnObjectWrapper.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/ConnObjectWrapper.java
@@ -19,29 +19,29 @@
 package org.apache.syncope.client.console.commons.status;
 
 import java.io.Serializable;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 
 public class ConnObjectWrapper implements Serializable {
 
     private static final long serialVersionUID = 9083721948999924299L;
 
-    private final AbstractAttributableTO attributable;
+    private final AnyTO any;
 
     private final String resourceName;
 
     private final ConnObjectTO connObjectTO;
 
-    public ConnObjectWrapper(final AbstractAttributableTO attributable, final String resourceName,
+    public ConnObjectWrapper(final AnyTO attributable, final String resourceName,
             final ConnObjectTO connObjectTO) {
 
-        this.attributable = attributable;
+        this.any = attributable;
         this.resourceName = resourceName;
         this.connObjectTO = connObjectTO;
     }
 
-    public AbstractAttributableTO getAttributable() {
-        return attributable;
+    public AnyTO getAny() {
+        return any;
     }
 
     public String getResourceName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
index 33bac29..af43c0a 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusBean.java
@@ -23,7 +23,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 
@@ -31,9 +31,9 @@ public class StatusBean implements Serializable {
 
     private static final long serialVersionUID = -5207260204921071129L;
 
-    private final Long attributableKey;
+    private final Long anyKey;
 
-    private final String attributableName;
+    private final String anyName;
 
     private final String resourceName;
 
@@ -43,10 +43,10 @@ public class StatusBean implements Serializable {
 
     private boolean linked = true;
 
-    public StatusBean(final AbstractAttributableTO attributable, final String resourceName) {
-        this.attributableKey = attributable.getKey();
-        this.attributableName = attributable instanceof UserTO
-                ? ((UserTO) attributable).getUsername() : ((GroupTO) attributable).getName();
+    public StatusBean(final AnyTO any, final String resourceName) {
+        this.anyKey = any.getKey();
+        this.anyName = any instanceof UserTO
+                ? ((UserTO) any).getUsername() : ((GroupTO) any).getName();
         this.resourceName = resourceName;
     }
 
@@ -70,12 +70,12 @@ public class StatusBean implements Serializable {
         this.status = status;
     }
 
-    public Long getAttributableId() {
-        return attributableKey;
+    public Long getAnyKey() {
+        return anyKey;
     }
 
-    public String getAttributableName() {
-        return attributableName;
+    public String getAnyName() {
+        return anyName;
     }
 
     public boolean isLinked() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
index 7a4a157..877a628 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/status/StatusUtils.java
@@ -27,10 +27,9 @@ import java.util.Map;
 import org.apache.syncope.client.console.commons.ConnIdSpecialAttributeName;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.ImagePanel;
-import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.common.lib.mod.StatusMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.wicket.Component;
@@ -49,56 +48,56 @@ public class StatusUtils implements Serializable {
 
     private static final String IMG_PREFIX = "/img/statuses/";
 
-    private final AbstractSubjectRestClient restClient;
+    private final AbstractAnyRestClient restClient;
 
-    public StatusUtils(final AbstractSubjectRestClient restClient) {
+    public StatusUtils(final AbstractAnyRestClient restClient) {
         this.restClient = restClient;
     }
 
-    public List<ConnObjectWrapper> getConnectorObjects(final AbstractSubjectTO subject) {
+    public List<ConnObjectWrapper> getConnectorObjects(final AnyTO any) {
         final List<ConnObjectWrapper> objects = new ArrayList<>();
-        objects.addAll(getConnectorObjects(subject, subject.getResources()));
+        objects.addAll(getConnectorObjects(any, any.getResources()));
         return objects;
     }
 
     public List<ConnObjectWrapper> getConnectorObjects(
-            final Collection<AbstractSubjectTO> subjects, final Collection<String> resources) {
+            final Collection<AnyTO> anys, final Collection<String> resources) {
 
         final List<ConnObjectWrapper> objects = new ArrayList<>();
 
-        for (AbstractSubjectTO subject : subjects) {
-            objects.addAll(getConnectorObjects(subject, resources));
+        for (AnyTO any : anys) {
+            objects.addAll(getConnectorObjects(any, resources));
         }
 
         return objects;
     }
 
     private List<ConnObjectWrapper> getConnectorObjects(
-            final AbstractSubjectTO subject, final Collection<String> resources) {
+            final AnyTO any, final Collection<String> resources) {
 
         final List<ConnObjectWrapper> objects = new ArrayList<>();
 
         for (String resourceName : resources) {
             ConnObjectTO objectTO = null;
             try {
-                objectTO = restClient.getConnectorObject(resourceName, subject.getKey());
+                objectTO = restClient.readConnObject(resourceName, any.getKey());
             } catch (Exception e) {
-                LOG.warn("ConnObject '{}' not found on resource '{}'", subject.getKey(), resourceName);
+                LOG.warn("ConnObject '{}' not found on resource '{}'", any.getKey(), resourceName);
             }
 
-            objects.add(new ConnObjectWrapper(subject, resourceName, objectTO));
+            objects.add(new ConnObjectWrapper(any, resourceName, objectTO));
         }
 
         return objects;
     }
 
     public StatusBean getStatusBean(
-            final AbstractAttributableTO attributable,
+            final AnyTO anyTO,
             final String resourceName,
             final ConnObjectTO objectTO,
             final boolean isGroup) {
 
-        final StatusBean statusBean = new StatusBean(attributable, resourceName);
+        final StatusBean statusBean = new StatusBean(anyTO, resourceName);
 
         if (objectTO != null) {
             final Boolean enabled = isEnabled(objectTO);
@@ -165,10 +164,10 @@ public class StatusUtils implements Serializable {
     }
 
     public ConnObjectTO getConnObjectTO(
-            final Long attributableId, final String resourceName, final List<ConnObjectWrapper> objects) {
+            final Long anyKey, final String resourceName, final List<ConnObjectWrapper> objects) {
 
         for (ConnObjectWrapper object : objects) {
-            if (attributableId.equals(object.getAttributable().getKey())
+            if (anyKey.equals(object.getAny().getKey())
                     && resourceName.equalsIgnoreCase(object.getResourceName())) {
 
                 return object.getConnObjectTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
new file mode 100644
index 0000000..b9a316d
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractAnyRestClient.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.rest;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+
+public abstract class AbstractAnyRestClient extends BaseRestClient {
+
+    private static final long serialVersionUID = 1962529678091410544L;
+
+    public abstract int count(String realm);
+
+    public abstract List<? extends AnyTO> list(
+            String realm, int page, int size, final SortParam<String> sort);
+
+    public abstract int searchCount(String realm, String fiql);
+
+    public abstract List<? extends AnyTO> search(
+            String realm, String fiql, int page, int size, final SortParam<String> sort);
+
+    public abstract ConnObjectTO readConnObject(String resourceName, Long key);
+
+    public abstract AnyTO delete(String etag, Long key);
+
+    public abstract BulkActionResult bulkAction(BulkAction action);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java
deleted file mode 100644
index 8b11b35..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.rest;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
-
-public abstract class AbstractSubjectRestClient extends BaseRestClient {
-
-    private static final long serialVersionUID = 1962529678091410544L;
-
-    public abstract int count(String realm);
-
-    public abstract List<? extends AbstractAttributableTO> list(
-            String realm, int page, int size, final SortParam<String> sort);
-
-    public abstract int searchCount(String realm, String fiql);
-
-    public abstract List<? extends AbstractSubjectTO> search(
-            String realm, String fiql, int page, int size, final SortParam<String> sort);
-
-    public abstract ConnObjectTO getConnectorObject(String resourceName, Long key);
-
-    public abstract AbstractSubjectTO delete(String etag, Long key);
-
-    public abstract BulkActionResult bulkAction(BulkAction action);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
index cc1501c..36b0d1c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
@@ -73,7 +73,7 @@ public class ConfigurationRestClient extends BaseRestClient {
             attrLayout.setSchema(type.getConfKey());
         }
         if (attrLayout.getValues().isEmpty()) {
-            attrLayout.getValues().addAll(schemaRestClient.getPlainSchemaNames(type.getAttrType()));
+            attrLayout.getValues().addAll(schemaRestClient.getPlainSchemaNames());
         }
 
         return attrLayout;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
index 64138bb..157de09 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
@@ -29,9 +29,9 @@ import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.ResourceService;
@@ -43,7 +43,7 @@ import org.springframework.stereotype.Component;
  * Console client for invoking Rest Group's services.
  */
 @Component
-public class GroupRestClient extends AbstractSubjectRestClient {
+public class GroupRestClient extends AbstractAnyRestClient {
 
     private static final long serialVersionUID = -8549081557283519638L;
 
@@ -80,8 +80,8 @@ public class GroupRestClient extends AbstractSubjectRestClient {
     }
 
     @Override
-    public ConnObjectTO getConnectorObject(final String resourceName, final Long id) {
-        return getService(ResourceService.class).getConnectorObject(resourceName, SubjectType.GROUP, id);
+    public ConnObjectTO readConnObject(final String resourceName, final Long id) {
+        return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.GROUP.name(), id);
     }
 
     public GroupTO create(final GroupTO groupTO) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index 87c9a3a..f5431db 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -21,14 +21,11 @@ package org.apache.syncope.client.console.rest;
 import java.util.List;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.syncope.common.lib.wrap.AnyKey;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.springframework.stereotype.Component;
 
@@ -84,11 +81,9 @@ public class ResourceRestClient extends BaseRestClient {
     }
 
     public BulkActionResult bulkAssociationAction(
-            final String resourceName, final Class<? extends AbstractAttributableTO> typeRef,
-            final ResourceDeassociationActionType type, final List<SubjectKey> subjtectIds) {
+            final String resourceName, final String anyTypeName,
+            final ResourceDeassociationActionType type, final List<AnyKey> anyKeys) {
 
-        return getService(ResourceService.class).bulkDeassociation(resourceName,
-                UserTO.class.isAssignableFrom(typeRef) ? SubjectType.USER : SubjectType.GROUP,
-                type, subjtectIds);
+        return getService(ResourceService.class).bulkDeassociation(resourceName, anyTypeName, type, anyKeys);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
index 6934ef6..9f7a6d2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
@@ -26,13 +26,12 @@ import java.util.ListIterator;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.AttrLayoutType;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.springframework.stereotype.Component;
@@ -62,27 +61,22 @@ public class SchemaRestClient extends BaseRestClient {
         }
     }
 
-    public List<? extends AbstractSchemaTO> getSchemas(final AttributableType attrType, final SchemaType schemaType) {
+    public List<? extends AbstractSchemaTO> getSchemas(final SchemaType schemaType) {
         List<? extends AbstractSchemaTO> schemas = Collections.emptyList();
 
         try {
-            schemas = getService(SchemaService.class).list(attrType, schemaType);
+            schemas = getService(SchemaService.class).list(schemaType);
         } catch (SyncopeClientException e) {
-            LOG.error("While getting all schemas for {} and {}", attrType, schemaType, e);
+            LOG.error("While getting all schemas for {}", schemaType, e);
         }
-
-        if (attrType == AttributableType.CONFIGURATION) {
-            filter(schemas, AttrLayoutType.confKeys(), false);
-        }
-
         return schemas;
     }
 
-    public List<PlainSchemaTO> getSchemas(final AttributableType type) {
+    public List<PlainSchemaTO> getSchemas() {
         List<PlainSchemaTO> schemas = null;
 
         try {
-            schemas = getService(SchemaService.class).list(type, SchemaType.PLAIN);
+            schemas = getService(SchemaService.class).list(SchemaType.PLAIN);
         } catch (SyncopeClientException e) {
             LOG.error("While getting all schemas", e);
         }
@@ -90,11 +84,11 @@ public class SchemaRestClient extends BaseRestClient {
         return schemas;
     }
 
-    public List<String> getSchemaNames(final AttributableType attrType, final SchemaType schemaType) {
+    public List<String> getSchemaNames(final SchemaType schemaType) {
         List<String> schemaNames = new ArrayList<>();
 
         try {
-            CollectionUtils.collect(getSchemas(attrType, schemaType), new Transformer<AbstractSchemaTO, String>() {
+            CollectionUtils.collect(getSchemas(schemaType), new Transformer<AbstractSchemaTO, String>() {
 
                 @Override
                 public String transform(final AbstractSchemaTO schemaTO) {
@@ -108,15 +102,15 @@ public class SchemaRestClient extends BaseRestClient {
         return schemaNames;
     }
 
-    public List<String> getPlainSchemaNames(final AttributableType type) {
-        return getSchemaNames(type, SchemaType.PLAIN);
+    public List<String> getPlainSchemaNames() {
+        return getSchemaNames(SchemaType.PLAIN);
     }
 
-    public List<DerSchemaTO> getDerSchemas(final AttributableType type) {
+    public List<DerSchemaTO> getDerSchemas() {
         List<DerSchemaTO> userDerSchemas = null;
 
         try {
-            userDerSchemas = getService(SchemaService.class).list(type, SchemaType.DERIVED);
+            userDerSchemas = getService(SchemaService.class).list(SchemaType.DERIVED);
         } catch (SyncopeClientException e) {
             LOG.error("While getting all user derived schemas", e);
         }
@@ -124,86 +118,86 @@ public class SchemaRestClient extends BaseRestClient {
         return userDerSchemas;
     }
 
-    public List<String> getDerSchemaNames(final AttributableType type) {
-        return getSchemaNames(type, SchemaType.DERIVED);
+    public List<String> getDerSchemaNames() {
+        return getSchemaNames(SchemaType.DERIVED);
     }
 
-    public List<VirSchemaTO> getVirSchemas(final AttributableType type) {
+    public List<VirSchemaTO> getVirSchemas() {
         List<VirSchemaTO> userVirSchemas = null;
 
         try {
-            userVirSchemas = getService(SchemaService.class).list(type, SchemaType.VIRTUAL);
+            userVirSchemas = getService(SchemaService.class).list(SchemaType.VIRTUAL);
         } catch (SyncopeClientException e) {
-            LOG.error("While getting all {} virtual schemas", type, e);
+            LOG.error("While getting all virtual schemas", e);
         }
 
         return userVirSchemas;
     }
 
-    public List<String> getVirSchemaNames(final AttributableType type) {
-        return getSchemaNames(type, SchemaType.VIRTUAL);
+    public List<String> getVirSchemaNames() {
+        return getSchemaNames(SchemaType.VIRTUAL);
     }
 
-    public void createPlainSchema(final AttributableType type, final PlainSchemaTO schemaTO) {
-        getService(SchemaService.class).create(type, SchemaType.PLAIN, schemaTO);
+    public void createPlainSchema(final PlainSchemaTO schemaTO) {
+        getService(SchemaService.class).create(SchemaType.PLAIN, schemaTO);
     }
 
-    public PlainSchemaTO readPlainSchema(final AttributableType type, final String name) {
+    public PlainSchemaTO readPlainSchema(final String name) {
         PlainSchemaTO schema = null;
 
         try {
-            schema = getService(SchemaService.class).read(type, SchemaType.PLAIN, name);
+            schema = getService(SchemaService.class).read(SchemaType.PLAIN, name);
         } catch (SyncopeClientException e) {
             LOG.error("While reading a user schema", e);
         }
         return schema;
     }
 
-    public void updatePlainSchema(final AttributableType type, final PlainSchemaTO schemaTO) {
-        getService(SchemaService.class).update(type, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+    public void updatePlainSchema(final PlainSchemaTO schemaTO) {
+        getService(SchemaService.class).update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
     }
 
-    public PlainSchemaTO deletePlainSchema(final AttributableType type, final String name) {
-        PlainSchemaTO response = getService(SchemaService.class).read(type, SchemaType.PLAIN, name);
-        getService(SchemaService.class).delete(type, SchemaType.PLAIN, name);
+    public PlainSchemaTO deletePlainSchema(final String name) {
+        PlainSchemaTO response = getService(SchemaService.class).read(SchemaType.PLAIN, name);
+        getService(SchemaService.class).delete(SchemaType.PLAIN, name);
         return response;
     }
 
-    public void createDerSchema(final AttributableType type, final DerSchemaTO schemaTO) {
-        getService(SchemaService.class).create(type, SchemaType.DERIVED, schemaTO);
+    public void createDerSchema(final DerSchemaTO schemaTO) {
+        getService(SchemaService.class).create(SchemaType.DERIVED, schemaTO);
     }
 
-    public DerSchemaTO readDerSchema(final AttributableType type, final String name) {
+    public DerSchemaTO readDerSchema(final String name) {
         DerSchemaTO derivedSchemaTO = null;
         try {
-            derivedSchemaTO = getService(SchemaService.class).read(type, SchemaType.DERIVED, name);
+            derivedSchemaTO = getService(SchemaService.class).read(SchemaType.DERIVED, name);
         } catch (SyncopeClientException e) {
             LOG.error("While reading a derived user schema", e);
         }
         return derivedSchemaTO;
     }
 
-    public void updateVirSchema(final AttributableType type, final VirSchemaTO schemaTO) {
-        getService(SchemaService.class).update(type, SchemaType.VIRTUAL, schemaTO.getKey(), schemaTO);
+    public void updateVirSchema(final VirSchemaTO schemaTO) {
+        getService(SchemaService.class).update(SchemaType.VIRTUAL, schemaTO.getKey(), schemaTO);
     }
 
-    public DerSchemaTO deleteDerSchema(final AttributableType type, final String name) {
-        DerSchemaTO schemaTO = getService(SchemaService.class).read(type, SchemaType.DERIVED, name);
-        getService(SchemaService.class).delete(type, SchemaType.DERIVED, name);
+    public DerSchemaTO deleteDerSchema(final String name) {
+        DerSchemaTO schemaTO = getService(SchemaService.class).read(SchemaType.DERIVED, name);
+        getService(SchemaService.class).delete(SchemaType.DERIVED, name);
         return schemaTO;
     }
 
-    public void createVirSchema(final AttributableType type, final VirSchemaTO schemaTO) {
-        getService(SchemaService.class).create(type, SchemaType.VIRTUAL, schemaTO);
+    public void createVirSchema(final VirSchemaTO schemaTO) {
+        getService(SchemaService.class).create(SchemaType.VIRTUAL, schemaTO);
     }
 
-    public void updateDerSchema(final AttributableType type, final DerSchemaTO schemaTO) {
-        getService(SchemaService.class).update(type, SchemaType.DERIVED, schemaTO.getKey(), schemaTO);
+    public void updateDerSchema(final DerSchemaTO schemaTO) {
+        getService(SchemaService.class).update(SchemaType.DERIVED, schemaTO.getKey(), schemaTO);
     }
 
-    public VirSchemaTO deleteVirSchema(final AttributableType type, final String name) {
-        VirSchemaTO schemaTO = getService(SchemaService.class).read(type, SchemaType.VIRTUAL, name);
-        getService(SchemaService.class).delete(type, SchemaType.VIRTUAL, name);
+    public VirSchemaTO deleteVirSchema(final String name) {
+        VirSchemaTO schemaTO = getService(SchemaService.class).read(SchemaType.VIRTUAL, name);
+        getService(SchemaService.class).delete(SchemaType.VIRTUAL, name);
         return schemaTO;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index a39df68..9d30b78 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -31,9 +31,9 @@ import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.ResourceService;
@@ -45,7 +45,7 @@ import org.springframework.stereotype.Component;
  * Console client for invoking rest users services.
  */
 @Component
-public class UserRestClient extends AbstractSubjectRestClient {
+public class UserRestClient extends AbstractAnyRestClient {
 
     private static final long serialVersionUID = -1575748964398293968L;
 
@@ -118,8 +118,8 @@ public class UserRestClient extends AbstractSubjectRestClient {
     }
 
     @Override
-    public ConnObjectTO getConnectorObject(final String resourceName, final Long id) {
-        return getService(ResourceService.class).getConnectorObject(resourceName, SubjectType.USER, id);
+    public ConnObjectTO readConnObject(final String resourceName, final Long id) {
+        return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.USER.name(), id);
     }
 
     public void suspend(final String etag, final long userId, final List<StatusBean> statuses) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
index eb0527e..2a078a0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/WorkflowRestClient.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.WorkflowService;
 import org.springframework.stereotype.Component;
@@ -39,7 +39,7 @@ public class WorkflowRestClient extends BaseRestClient {
     }
 
     public InputStream getDefinition(final MediaType mediaType) {
-        Response response = getService(mediaType).exportDefinition(SubjectType.USER);
+        Response response = getService(mediaType).exportDefinition(AnyTypeKind.USER);
 
         return (InputStream) response.getEntity();
     }
@@ -47,7 +47,7 @@ public class WorkflowRestClient extends BaseRestClient {
     public byte[] getDiagram() {
         WorkflowService service = getService(WorkflowService.class);
         WebClient.client(service).accept(RESTHeaders.MEDIATYPE_IMAGE_PNG);
-        Response response = service.exportDiagram(SubjectType.USER);
+        Response response = service.exportDiagram(AnyTypeKind.USER);
 
         byte[] diagram;
         try {
@@ -64,6 +64,6 @@ public class WorkflowRestClient extends BaseRestClient {
     }
 
     public void updateDefinition(final MediaType mediaType, final String definition) {
-        getService(mediaType).importDefinition(SubjectType.USER, definition);
+        getService(mediaType).importDefinition(AnyTypeKind.USER, definition);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index 1bfbb4f..4773150 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@ -31,8 +31,8 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.builders.ListQueryBuilder;
-import org.apache.syncope.client.lib.builders.SubjectListQueryBuilder;
-import org.apache.syncope.client.lib.builders.SubjectSearchQueryBuilder;
+import org.apache.syncope.client.lib.builders.AnyListQueryBuilder;
+import org.apache.syncope.client.lib.builders.AnySearchQueryBuilder;
 import org.apache.syncope.common.lib.search.OrderByClauseBuilder;
 import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
@@ -108,24 +108,24 @@ public class SyncopeClient {
     }
 
     /**
-     * Returns a new instance of {@link SubjectListQueryBuilder}, for assisted building of some service's {@code list()}
+     * Returns a new instance of {@link AnyListQueryBuilder}, for assisted building of some service's {@code list()}
      * arguments.
      *
-     * @return default instance of {@link SubjectListQueryBuilder}
+     * @return default instance of {@link AnyListQueryBuilder}
      */
-    public static SubjectListQueryBuilder getSubjectListQueryBuilder() {
-        return new SubjectListQueryBuilder();
+    public static AnyListQueryBuilder getSubjectListQueryBuilder() {
+        return new AnyListQueryBuilder();
     }
 
     /**
-     * Returns a new instance of {@link SubjectSearchQueryBuilder}, for assisted building of some service's
+     * Returns a new instance of {@link AnySearchQueryBuilder}, for assisted building of some service's
      * {@code search()}
      * arguments.
      *
-     * @return default instance of {@link SubjectSearchQueryBuilder}
+     * @return default instance of {@link AnySearchQueryBuilder}
      */
-    public static SubjectSearchQueryBuilder getSubjectSearchQueryBuilder() {
-        return new SubjectSearchQueryBuilder();
+    public static AnySearchQueryBuilder getSubjectSearchQueryBuilder() {
+        return new AnySearchQueryBuilder();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
new file mode 100644
index 0000000..62e4bbe
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnyListQueryBuilder.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.lib.builders;
+
+import java.util.ArrayList;
+import org.apache.syncope.common.rest.api.beans.ListQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+
+public class AnyListQueryBuilder extends ListQueryBuilder {
+
+    private final AnyListQuery instance = new AnyListQuery();
+
+    @Override
+    public AnyListQueryBuilder page(final Integer page) {
+        return AnyListQueryBuilder.class.cast(super.page(page));
+    }
+
+    @Override
+    public AnyListQueryBuilder size(final Integer size) {
+        return AnyListQueryBuilder.class.cast(super.size(size));
+    }
+
+    @Override
+    public AnyListQueryBuilder orderBy(final String orderBy) {
+        return AnyListQueryBuilder.class.cast(super.orderBy(orderBy));
+    }
+
+    public AnyListQueryBuilder realm(final String realm) {
+        if (instance.getRealms() == null) {
+            instance.setRealms(new ArrayList<String>());
+        }
+
+        return this;
+    }
+
+    @Override
+    public AnyListQuery build() {
+        ListQuery lq = super.build();
+        instance.setPage(lq.getPage());
+        instance.setSize(lq.getSize());
+        instance.setOrderBy(lq.getOrderBy());
+
+        return instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
new file mode 100644
index 0000000..c3fce47
--- /dev/null
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/AnySearchQueryBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.lib.builders;
+
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+
+public class AnySearchQueryBuilder extends AnyListQueryBuilder {
+
+    private final AnySearchQuery instance = new AnySearchQuery();
+
+    @Override
+    public AnySearchQueryBuilder realm(final String realm) {
+        return AnySearchQueryBuilder.class.cast(super.realm(realm));
+    }
+
+    @Override
+    public AnySearchQueryBuilder page(final Integer page) {
+        return AnySearchQueryBuilder.class.cast(super.page(page));
+    }
+
+    @Override
+    public AnySearchQueryBuilder size(final Integer size) {
+        return AnySearchQueryBuilder.class.cast(super.size(size));
+    }
+
+    @Override
+    public AnySearchQueryBuilder orderBy(final String orderBy) {
+        return AnySearchQueryBuilder.class.cast(super.orderBy(orderBy));
+    }
+
+    public AnySearchQueryBuilder fiql(final String fiql) {
+        instance.setFiql(fiql);
+
+        return this;
+    }
+
+    @Override
+    public AnySearchQuery build() {
+        AnyListQuery slq = super.build();
+        instance.setRealms(slq.getRealms());
+        instance.setPage(slq.getPage());
+        instance.setSize(slq.getSize());
+        instance.setOrderBy(slq.getOrderBy());
+
+        return instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectListQueryBuilder.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectListQueryBuilder.java b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectListQueryBuilder.java
deleted file mode 100644
index 6aec945..0000000
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectListQueryBuilder.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.lib.builders;
-
-import java.util.ArrayList;
-import org.apache.syncope.common.rest.api.beans.ListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-
-public class SubjectListQueryBuilder extends ListQueryBuilder {
-
-    private final SubjectListQuery instance = new SubjectListQuery();
-
-    @Override
-    public SubjectListQueryBuilder page(final Integer page) {
-        return SubjectListQueryBuilder.class.cast(super.page(page));
-    }
-
-    @Override
-    public SubjectListQueryBuilder size(final Integer size) {
-        return SubjectListQueryBuilder.class.cast(super.size(size));
-    }
-
-    @Override
-    public SubjectListQueryBuilder orderBy(final String orderBy) {
-        return SubjectListQueryBuilder.class.cast(super.orderBy(orderBy));
-    }
-
-    public SubjectListQueryBuilder realm(final String realm) {
-        if (instance.getRealms() == null) {
-            instance.setRealms(new ArrayList<String>());
-        }
-
-        return this;
-    }
-
-    @Override
-    public SubjectListQuery build() {
-        ListQuery lq = super.build();
-        instance.setPage(lq.getPage());
-        instance.setSize(lq.getSize());
-        instance.setOrderBy(lq.getOrderBy());
-
-        return instance;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectSearchQueryBuilder.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectSearchQueryBuilder.java b/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectSearchQueryBuilder.java
deleted file mode 100644
index b74860e..0000000
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/builders/SubjectSearchQueryBuilder.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.client.lib.builders;
-
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
-
-public class SubjectSearchQueryBuilder extends SubjectListQueryBuilder {
-
-    private final SubjectSearchQuery instance = new SubjectSearchQuery();
-
-    @Override
-    public SubjectSearchQueryBuilder realm(final String realm) {
-        return SubjectSearchQueryBuilder.class.cast(super.realm(realm));
-    }
-
-    @Override
-    public SubjectSearchQueryBuilder page(final Integer page) {
-        return SubjectSearchQueryBuilder.class.cast(super.page(page));
-    }
-
-    @Override
-    public SubjectSearchQueryBuilder size(final Integer size) {
-        return SubjectSearchQueryBuilder.class.cast(super.size(size));
-    }
-
-    @Override
-    public SubjectSearchQueryBuilder orderBy(final String orderBy) {
-        return SubjectSearchQueryBuilder.class.cast(super.orderBy(orderBy));
-    }
-
-    public SubjectSearchQueryBuilder fiql(final String fiql) {
-        instance.setFiql(fiql);
-
-        return this;
-    }
-
-    @Override
-    public SubjectSearchQuery build() {
-        SubjectListQuery slq = super.build();
-        instance.setRealms(slq.getRealms());
-        instance.setPage(slq.getPage());
-        instance.setSize(slq.getSize());
-        instance.setOrderBy(slq.getOrderBy());
-
-        return instance;
-    }
-}


[16/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
deleted file mode 100644
index 2fa54c3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAExternalResource.java
+++ /dev/null
@@ -1,428 +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;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.persistence.Basic;
-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.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import javax.validation.constraints.NotNull;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PropagationMode;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-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.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMapping;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMapping;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-/**
- * Resource for propagation and synchronization.
- */
-@Entity
-@Table(name = JPAExternalResource.TABLE)
-@ExternalResourceCheck
-public class JPAExternalResource extends AbstractAnnotatedEntity<String> implements ExternalResource {
-
-    private static final long serialVersionUID = -6937712883512073278L;
-
-    public static final String TABLE = "ExternalResource";
-
-    /**
-     * The resource identifier is the name.
-     */
-    @Id
-    private String name;
-
-    /**
-     * Should this resource enforce the mandatory constraints?
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer enforceMandatoryCondition;
-
-    /**
-     * The resource type is identified by the associated connector.
-     */
-    @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
-    @NotNull
-    private JPAConnInstance connector;
-
-    /**
-     * Mapping for user objects.
-     */
-    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "resource")
-    private JPAUMapping umapping;
-
-    /**
-     * Mapping for group objects.
-     */
-    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "resource")
-    private JPAGMapping rmapping;
-
-    /**
-     * Is this resource primary, for propagations?
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer propagationPrimary;
-
-    /**
-     * Priority index for propagation ordering.
-     */
-    @Column(nullable = false)
-    private Integer propagationPriority;
-
-    /**
-     * Generate random password for propagation, if not provided?
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer randomPwdIfNotProvided;
-
-    @Enumerated(EnumType.STRING)
-    @Column(nullable = false)
-    private PropagationMode propagationMode;
-
-    @Enumerated(EnumType.STRING)
-    @Column(nullable = false)
-    private TraceLevel createTraceLevel;
-
-    @Enumerated(EnumType.STRING)
-    @Column(nullable = false)
-    private TraceLevel updateTraceLevel;
-
-    @Enumerated(EnumType.STRING)
-    @Column(nullable = false)
-    private TraceLevel deleteTraceLevel;
-
-    @Enumerated(EnumType.STRING)
-    @Column(nullable = false)
-    private TraceLevel syncTraceLevel;
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAPasswordPolicy passwordPolicy;
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAAccountPolicy accountPolicy;
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPASyncPolicy syncPolicy;
-
-    /**
-     * Configuration properties that are overridden from the connector instance.
-     */
-    @Lob
-    private String jsonConf;
-
-    /**
-     * SyncToken for calling ConnId's sync() on users.
-     */
-    @Lob
-    private String userializedSyncToken;
-
-    /**
-     * SyncToken for calling ConnId's sync() on groups.
-     */
-    @Lob
-    private String rserializedSyncToken;
-
-    /**
-     * (Optional) classes for PropagationAction.
-     */
-    @ElementCollection(fetch = FetchType.EAGER)
-    @Column(name = "actionClassName")
-    @CollectionTable(name = "ExternalResource_PropActions",
-            joinColumns =
-            @JoinColumn(name = "ExternalResource_name", referencedColumnName = "name"))
-    private List<String> propagationActionsClassNames = new ArrayList<>();
-
-    /**
-     * Default constructor.
-     */
-    public JPAExternalResource() {
-        super();
-
-        enforceMandatoryCondition = getBooleanAsInteger(false);
-        propagationPrimary = 0;
-        propagationPriority = 0;
-        randomPwdIfNotProvided = 0;
-        propagationMode = PropagationMode.TWO_PHASES;
-
-        createTraceLevel = TraceLevel.FAILURES;
-        updateTraceLevel = TraceLevel.FAILURES;
-        deleteTraceLevel = TraceLevel.FAILURES;
-        syncTraceLevel = TraceLevel.FAILURES;
-    }
-
-    @Override
-    public boolean isEnforceMandatoryCondition() {
-        return isBooleanAsInteger(enforceMandatoryCondition);
-    }
-
-    @Override
-    public void setEnforceMandatoryCondition(final boolean enforceMandatoryCondition) {
-        this.enforceMandatoryCondition = getBooleanAsInteger(enforceMandatoryCondition);
-    }
-
-    @Override
-    public ConnInstance getConnector() {
-        return connector;
-    }
-
-    @Override
-    public void setConnector(final ConnInstance connector) {
-        checkType(connector, JPAConnInstance.class);
-        this.connector = (JPAConnInstance) connector;
-    }
-
-    @Override
-    public UMapping getUmapping() {
-        return umapping;
-    }
-
-    @Override
-    public void setUmapping(final UMapping umapping) {
-        checkType(umapping, JPAUMapping.class);
-        this.umapping = (JPAUMapping) umapping;
-    }
-
-    @Override
-    public GMapping getGmapping() {
-        return rmapping;
-    }
-
-    @Override
-    public void setGmapping(final GMapping gmapping) {
-        checkType(gmapping, JPAGMapping.class);
-        this.rmapping = (JPAGMapping) gmapping;
-    }
-
-    @Override
-    public boolean isPropagationPrimary() {
-        return isBooleanAsInteger(propagationPrimary);
-    }
-
-    @Override
-    public void setPropagationPrimary(final boolean propagationPrimary) {
-        this.propagationPrimary = getBooleanAsInteger(propagationPrimary);
-    }
-
-    @Override
-    public Integer getPropagationPriority() {
-        return propagationPriority;
-    }
-
-    @Override
-    public void setPropagationPriority(final Integer propagationPriority) {
-        if (propagationPriority != null) {
-            this.propagationPriority = propagationPriority;
-        }
-    }
-
-    @Override
-    public boolean isRandomPwdIfNotProvided() {
-        return isBooleanAsInteger(randomPwdIfNotProvided);
-    }
-
-    @Override
-    public void setRandomPwdIfNotProvided(final boolean randomPwdIfNotProvided) {
-        this.randomPwdIfNotProvided = getBooleanAsInteger(randomPwdIfNotProvided);
-    }
-
-    @Override
-    public PropagationMode getPropagationMode() {
-        return propagationMode;
-    }
-
-    @Override
-    public void setPropagationMode(final PropagationMode propagationMode) {
-        this.propagationMode = propagationMode;
-    }
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String name) {
-        this.name = name;
-    }
-
-    @Override
-    public TraceLevel getCreateTraceLevel() {
-        return createTraceLevel;
-    }
-
-    @Override
-    public void setCreateTraceLevel(final TraceLevel createTraceLevel) {
-        this.createTraceLevel = createTraceLevel;
-    }
-
-    @Override
-
-    public TraceLevel getDeleteTraceLevel() {
-        return deleteTraceLevel;
-    }
-
-    @Override
-    public void setDeleteTraceLevel(final TraceLevel deleteTraceLevel) {
-        this.deleteTraceLevel = deleteTraceLevel;
-    }
-
-    @Override
-    public TraceLevel getUpdateTraceLevel() {
-        return updateTraceLevel;
-    }
-
-    @Override
-    public void setUpdateTraceLevel(final TraceLevel updateTraceLevel) {
-        this.updateTraceLevel = updateTraceLevel;
-    }
-
-    @Override
-    public TraceLevel getSyncTraceLevel() {
-        return syncTraceLevel;
-    }
-
-    @Override
-    public void setSyncTraceLevel(final TraceLevel syncTraceLevel) {
-        this.syncTraceLevel = syncTraceLevel;
-    }
-
-    @Override
-    public AccountPolicy getAccountPolicy() {
-        return accountPolicy;
-    }
-
-    @Override
-    public void setAccountPolicy(final AccountPolicy accountPolicy) {
-        checkType(accountPolicy, JPAAccountPolicy.class);
-        this.accountPolicy = (JPAAccountPolicy) accountPolicy;
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    @Override
-    public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
-        checkType(passwordPolicy, JPAPasswordPolicy.class);
-        this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
-    }
-
-    @Override
-    public SyncPolicy getSyncPolicy() {
-        return syncPolicy;
-    }
-
-    @Override
-    public void setSyncPolicy(final SyncPolicy syncPolicy) {
-        checkType(syncPolicy, JPASyncPolicy.class);
-        this.syncPolicy = (JPASyncPolicy) syncPolicy;
-    }
-
-    @Override
-    public Set<ConnConfProperty> getConnInstanceConfiguration() {
-        Set<ConnConfProperty> configuration = new HashSet<>();
-        if (!StringUtils.isBlank(jsonConf)) {
-            CollectionUtils.addAll(configuration, POJOHelper.deserialize(jsonConf, ConnConfProperty[].class));
-        }
-
-        return configuration;
-    }
-
-    @Override
-    public void setConnInstanceConfiguration(final Set<ConnConfProperty> properties) {
-        jsonConf = POJOHelper.serialize(new HashSet<>(properties));
-    }
-
-    @Override
-    public String getSerializedUSyncToken() {
-        return userializedSyncToken;
-    }
-
-    @Override
-    public SyncToken getUsyncToken() {
-        return userializedSyncToken == null
-                ? null
-                : POJOHelper.deserialize(userializedSyncToken, SyncToken.class);
-    }
-
-    @Override
-    public void setUsyncToken(final SyncToken syncToken) {
-        this.userializedSyncToken = syncToken == null ? null : POJOHelper.serialize(syncToken);
-    }
-
-    @Override
-    public String getSerializedRSyncToken() {
-        return rserializedSyncToken;
-    }
-
-    @Override
-    public SyncToken getRsyncToken() {
-        return rserializedSyncToken == null
-                ? null
-                : POJOHelper.deserialize(rserializedSyncToken, SyncToken.class);
-    }
-
-    @Override
-    public void setRsyncToken(final SyncToken syncToken) {
-        this.rserializedSyncToken = syncToken == null ? null : POJOHelper.serialize(syncToken);
-    }
-
-    @Override
-    public List<String> getPropagationActionsClassNames() {
-        return propagationActionsClassNames;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
index 498032e..7e3d211 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPANotification.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import javax.persistence.Basic;
+import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
@@ -31,12 +32,17 @@ import javax.persistence.Enumerated;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.persistence.jpa.validation.entity.NotificationCheck;
 
@@ -56,19 +62,18 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio
     @Column(name = "event")
     @CollectionTable(name = "Notification_events",
             joinColumns =
-            @JoinColumn(name = "Notification_id", referencedColumnName = "id"))
+            @JoinColumn(name = "notification_id", referencedColumnName = "id"))
     private List<String> events;
 
-    private String userAbout;
-
-    private String groupAbout;
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "notification")
+    private List<JPAAnyAbout> abouts;
 
     private String recipients;
 
     @ElementCollection(fetch = FetchType.EAGER)
     @CollectionTable(name = "Notification_staticRecipients",
             joinColumns =
-            @JoinColumn(name = "Notification_id", referencedColumnName = "id"))
+            @JoinColumn(name = "notification_id", referencedColumnName = "id"))
     @Column(name = "staticRecipients")
     private List<String> staticRecipients;
 
@@ -106,6 +111,7 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio
 
     public JPANotification() {
         events = new ArrayList<>();
+        abouts = new ArrayList<>();
         staticRecipients = new ArrayList<>();
         selfAsRecipient = getBooleanAsInteger(false);
         active = getBooleanAsInteger(true);
@@ -118,26 +124,6 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio
     }
 
     @Override
-    public String getUserAbout() {
-        return userAbout;
-    }
-
-    @Override
-    public void setUserAbout(final String userAbout) {
-        this.userAbout = userAbout;
-    }
-
-    @Override
-    public String getGroupAbout() {
-        return groupAbout;
-    }
-
-    @Override
-    public void setGroupAbout(final String groupAbout) {
-        this.groupAbout = groupAbout;
-    }
-
-    @Override
     public String getRecipients() {
         return recipients;
     }
@@ -174,6 +160,34 @@ public class JPANotification extends AbstractEntity<Long> implements Notificatio
     }
 
     @Override
+    public boolean add(final AnyAbout about) {
+        checkType(about, JPAAnyAbout.class);
+        return this.abouts.add((JPAAnyAbout) about);
+    }
+
+    @Override
+    public boolean remove(final AnyAbout about) {
+        checkType(about, JPAAnyAbout.class);
+        return this.abouts.remove((JPAAnyAbout) about);
+    }
+
+    @Override
+    public AnyAbout getAbout(final AnyType anyType) {
+        return CollectionUtils.find(abouts, new Predicate<AnyAbout>() {
+
+            @Override
+            public boolean evaluate(final AnyAbout about) {
+                return anyType != null && anyType.equals(about.getAnyType());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends AnyAbout> getAbouts() {
+        return abouts;
+    }
+
+    @Override
     public List<String> getStaticRecipients() {
         return staticRecipients;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
new file mode 100644
index 0000000..5f767e0
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
@@ -0,0 +1,276 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator;
+import org.apache.syncope.core.persistence.jpa.validation.entity.PlainSchemaCheck;
+import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
+
+@Entity
+@Table(name = JPAPlainSchema.TABLE)
+@PlainSchemaCheck
+@SchemaNameCheck
+public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchema {
+
+    private static final long serialVersionUID = -8621028596062054739L;
+
+    public static final String TABLE = "PlainSchema";
+
+    @Id
+    private String name;
+
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private AttrSchemaType type;
+
+    @Column(nullable = false)
+    private String mandatoryCondition;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer multivalue;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer uniqueConstraint;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer readonly;
+
+    @Column(nullable = true)
+    private String conversionPattern;
+
+    @Column(nullable = true)
+    private String validatorClass;
+
+    @Column(nullable = true)
+    @Lob
+    private String enumerationValues;
+
+    @Column(nullable = true)
+    @Lob
+    private String enumerationKeys;
+
+    @Column(nullable = true)
+    private String secretKey;
+
+    @Column(nullable = true)
+    @Enumerated(EnumType.STRING)
+    private CipherAlgorithm cipherAlgorithm;
+
+    @Column(nullable = true)
+    private String mimeType;
+
+    @Transient
+    private Validator validator;
+
+    public JPAPlainSchema() {
+        super();
+
+        type = AttrSchemaType.String;
+        mandatoryCondition = Boolean.FALSE.toString();
+        multivalue = getBooleanAsInteger(false);
+        uniqueConstraint = getBooleanAsInteger(false);
+        readonly = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public AttrSchemaType getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(final AttrSchemaType type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    @Override
+    public void setMandatoryCondition(final String condition) {
+        this.mandatoryCondition = condition;
+    }
+
+    @Override
+    public boolean isMultivalue() {
+        return isBooleanAsInteger(multivalue);
+    }
+
+    @Override
+    public void setMultivalue(final boolean multivalue) {
+        this.multivalue = getBooleanAsInteger(multivalue);
+    }
+
+    @Override
+    public boolean isUniqueConstraint() {
+        return isBooleanAsInteger(uniqueConstraint);
+    }
+
+    @Override
+    public void setUniqueConstraint(final boolean uniquevalue) {
+        this.uniqueConstraint = getBooleanAsInteger(uniquevalue);
+    }
+
+    @Override
+    public boolean isReadonly() {
+        return isBooleanAsInteger(readonly);
+    }
+
+    @Override
+    public void setReadonly(final boolean readonly) {
+        this.readonly = getBooleanAsInteger(readonly);
+    }
+
+    @Override
+    public Validator getValidator() {
+        if (validator != null) {
+            return validator;
+        }
+
+        if (getValidatorClass() != null && getValidatorClass().length() > 0) {
+            try {
+                Constructor<?> validatorConstructor = Class.forName(getValidatorClass()).
+                        getConstructor(new Class<?>[] { PlainSchema.class });
+                validator = (Validator) validatorConstructor.newInstance(this);
+            } catch (Exception e) {
+                LOG.error("Could not instantiate validator of type {}, reverting to {}",
+                        getValidatorClass(), BasicValidator.class.getSimpleName(), e);
+            }
+        }
+
+        if (validator == null) {
+            validator = new BasicValidator(this);
+        }
+
+        return validator;
+    }
+
+    @Override
+    public String getValidatorClass() {
+        return validatorClass;
+    }
+
+    @Override
+    public void setValidatorClass(final String validatorClass) {
+        this.validatorClass = validatorClass;
+    }
+
+    @Override
+    public String getEnumerationValues() {
+        return enumerationValues;
+    }
+
+    @Override
+    public void setEnumerationValues(final String enumerationValues) {
+        this.enumerationValues = enumerationValues;
+    }
+
+    @Override
+    public String getEnumerationKeys() {
+        return enumerationKeys;
+    }
+
+    @Override
+    public void setEnumerationKeys(final String enumerationKeys) {
+        this.enumerationKeys = enumerationKeys;
+    }
+
+    @Override
+    public String getConversionPattern() {
+        if (!getType().isConversionPatternNeeded()) {
+            LOG.debug("Conversion pattern is not needed: {}'s type is {}", this, getType());
+        }
+
+        return conversionPattern;
+    }
+
+    @Override
+    public void setConversionPattern(final String conversionPattern) {
+        if (StringUtils.isNotBlank(conversionPattern) && !getType().isConversionPatternNeeded()) {
+            LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType());
+        }
+
+        this.conversionPattern = conversionPattern;
+    }
+
+    @Override
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    @Override
+    public void setSecretKey(final String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    @Override
+    public CipherAlgorithm getCipherAlgorithm() {
+        return cipherAlgorithm;
+    }
+
+    @Override
+    public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) {
+        this.cipherAlgorithm = cipherAlgorithm;
+    }
+
+    @Override
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    @Override
+    public void setMimeType(final String mimeType) {
+        this.mimeType = mimeType;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
index 0360f54..4969497 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
+import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -37,7 +38,7 @@ import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..f7cf717
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import javax.persistence.Basic;
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
+
+@Entity
+@Table(name = JPAVirSchema.TABLE)
+@Cacheable
+@SchemaNameCheck
+public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
+
+    private static final long serialVersionUID = 3274006935328590141L;
+
+    public static final String TABLE = "VirSchema";
+
+    @Id
+    private String name;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer readonly;
+
+    public JPAVirSchema() {
+        super();
+
+        readonly = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String key) {
+        this.name = key;
+    }
+
+    @Override
+    public AttrSchemaType getType() {
+        return AttrSchemaType.String;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return Boolean.FALSE.toString().toLowerCase();
+    }
+
+    @Override
+    public boolean isMultivalue() {
+        return Boolean.TRUE;
+    }
+
+    @Override
+    public boolean isUniqueConstraint() {
+        return Boolean.FALSE;
+    }
+
+    @Override
+    public boolean isReadonly() {
+        return isBooleanAsInteger(readonly);
+    }
+
+    @Override
+    public void setReadonly(final boolean readonly) {
+        this.readonly = getBooleanAsInteger(readonly);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAttributableUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAttributableUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAttributableUtilsFactory.java
deleted file mode 100644
index e132601..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAttributableUtilsFactory.java
+++ /dev/null
@@ -1,81 +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;
-
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.conf.Conf;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.springframework.stereotype.Component;
-
-@Component
-public class JPAttributableUtilsFactory implements AttributableUtilsFactory {
-
-    @Override
-    public AttributableUtils getInstance(final AttributableType type) {
-        return new JPAAttributableUtils(type);
-    }
-
-    @Override
-    public AttributableUtils getInstance(final String attributableType) {
-        return new JPAAttributableUtils(AttributableType.valueOf(attributableType));
-    }
-
-    @Override
-    public AttributableUtils getInstance(final ObjectClass objectClass) {
-        AttributableType type = null;
-        if (ObjectClass.ACCOUNT.equals(objectClass)) {
-            type = AttributableType.USER;
-        } else if (ObjectClass.GROUP.equals(objectClass)) {
-            type = AttributableType.GROUP;
-        }
-
-        if (type == null) {
-            throw new IllegalArgumentException("ObjectClass not supported: " + objectClass);
-        }
-
-        return new JPAAttributableUtils(type);
-    }
-
-    @Override
-    public AttributableUtils getInstance(final Attributable<?, ?, ?> attributable) {
-        AttributableType type = null;
-        if (attributable instanceof User) {
-            type = AttributableType.USER;
-        } else if (attributable instanceof Group) {
-            type = AttributableType.GROUP;
-        } else if (attributable instanceof Membership) {
-            type = AttributableType.MEMBERSHIP;
-        } else if (attributable instanceof Conf) {
-            type = AttributableType.CONFIGURATION;
-        }
-
-        if (type == null) {
-            throw new IllegalArgumentException("Attributable type not supported: " + attributable.getClass().getName());
-        }
-
-        return new JPAAttributableUtils(type);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADerAttr.java
new file mode 100644
index 0000000..abd6676
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADerAttr.java
@@ -0,0 +1,50 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADerAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
+
+@Entity
+@Table(name = JPAADerAttr.TABLE)
+public class JPAADerAttr extends AbstractDerAttr<AnyObject> implements ADerAttr {
+
+    private static final long serialVersionUID = 5828533701103533330L;
+
+    public static final String TABLE = "ADerAttr";
+
+    @ManyToOne
+    private JPAAnyObject owner;
+
+    @Override
+    public AnyObject getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final AnyObject owner) {
+        checkType(owner, JPAAnyObject.class);
+        this.owner = (JPAAnyObject) owner;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
new file mode 100644
index 0000000..c12b855
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java
@@ -0,0 +1,89 @@
+/*
+ * 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.anyobject;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+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.jpa.entity.AbstractDynMembership;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAADynGroupMembership.TABLE)
+public class JPAADynGroupMembership extends AbstractDynMembership<AnyObject> implements ADynGroupMembership {
+
+    private static final long serialVersionUID = -7336814163949640354L;
+
+    public static final String TABLE = "ADynGroupMembership";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPAGroup group;
+
+    @ManyToMany
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "aDynGroupMembership_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyObject_id"))
+    private List<JPAAnyObject> anyObjects = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Group getGroup() {
+        return group;
+    }
+
+    @Override
+    public void setGroup(final Group role) {
+        checkType(role, JPAGroup.class);
+        this.group = (JPAGroup) role;
+    }
+
+    @Override
+    public boolean add(final AnyObject anyObject) {
+        checkType(anyObject, JPAAnyObject.class);
+        return anyObjects.add((JPAAnyObject) anyObject);
+    }
+
+    @Override
+    public boolean remove(final AnyObject anyObject) {
+        checkType(anyObject, JPAAnyObject.class);
+        return anyObjects.remove((JPAAnyObject) anyObject);
+    }
+
+    @Override
+    public List<? extends AnyObject> getMembers() {
+        return anyObjects;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java
new file mode 100644
index 0000000..e770e33
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java
@@ -0,0 +1,77 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+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.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAAMembership.TABLE)
+public class JPAAMembership extends AbstractEntity<Long> implements AMembership {
+
+    private static final long serialVersionUID = 1503557547394601405L;
+
+    public static final String TABLE = "AMembership";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @Column(name = "anyObject_id")
+    private JPAAnyObject leftEnd;
+
+    @ManyToOne
+    @Column(name = "group_id")
+    private JPAGroup rightEnd;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public AnyObject getLeftEnd() {
+        return leftEnd;
+    }
+
+    @Override
+    public void setLeftEnd(final AnyObject leftEnd) {
+        checkType(leftEnd, JPAAnyObject.class);
+        this.leftEnd = (JPAAnyObject) leftEnd;
+    }
+
+    @Override
+    public JPAGroup getRightEnd() {
+        return rightEnd;
+    }
+
+    @Override
+    public void setRightEnd(final Group rightEnd) {
+        checkType(rightEnd, JPAGroup.class);
+        this.rightEnd = (JPAGroup) rightEnd;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
new file mode 100644
index 0000000..46c1680
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java
@@ -0,0 +1,105 @@
+/*
+ * 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.anyobject;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.validation.Valid;
+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.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
+
+@Entity
+@Table(name = JPAAPlainAttr.TABLE)
+public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlainAttr {
+
+    private static final long serialVersionUID = 8066058729580952116L;
+
+    public static final String TABLE = "APlainAttr";
+
+    @Id
+    private Long id;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAnyObject owner;
+
+    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @Valid
+    private List<JPAAPlainAttrValue> values = new ArrayList<>();
+
+    @OneToOne(cascade = CascadeType.ALL, mappedBy = "attribute")
+    @Valid
+    private JPAAPlainAttrUniqueValue uniqueValue;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public AnyObject getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final AnyObject owner) {
+        checkType(owner, JPAAnyObject.class);
+        this.owner = (JPAAnyObject) owner;
+    }
+
+    @Override
+    protected boolean addForMultiValue(final PlainAttrValue attrValue) {
+        checkType(attrValue, JPAAPlainAttrValue.class);
+        return values.add((JPAAPlainAttrValue) attrValue);
+    }
+
+    @Override
+    public boolean remove(final PlainAttrValue attrValue) {
+        checkType(attrValue, JPAAPlainAttrValue.class);
+        return values.remove((JPAAPlainAttrValue) attrValue);
+    }
+
+    @Override
+    public List<? extends APlainAttrValue> getValues() {
+        return values;
+    }
+
+    @Override
+    public APlainAttrUniqueValue getUniqueValue() {
+        return uniqueValue;
+    }
+
+    @Override
+    public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) {
+        checkType(owner, JPAAPlainAttrUniqueValue.class);
+        this.uniqueValue = (JPAAPlainAttrUniqueValue) uniqueValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java
new file mode 100644
index 0000000..25cc5eb
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java
@@ -0,0 +1,78 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
+
+@Entity
+@Table(name = JPAAPlainAttrUniqueValue.TABLE)
+public class JPAAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue {
+
+    private static final long serialVersionUID = -6412206895091662679L;
+
+    public static final String TABLE = "APlainAttrUniqueValue";
+
+    @Id
+    private Long id;
+
+    @OneToOne(optional = false)
+    private JPAAPlainAttr attribute;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "schema_name")
+    private JPAPlainSchema schema;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public APlainAttr getAttr() {
+        return attribute;
+    }
+
+    @Override
+    public void setAttr(final PlainAttr attr) {
+        checkType(attr, JPAAPlainAttr.class);
+        this.attribute = (JPAAPlainAttr) attr;
+    }
+
+    @Override
+    public PlainSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java
new file mode 100644
index 0000000..73c962c
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java
@@ -0,0 +1,64 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+
+@Entity
+@Table(name = JPAAPlainAttrValue.TABLE)
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class JPAAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue {
+
+    private static final long serialVersionUID = -2965487882824889272L;
+
+    public static final String TABLE = "APlainAttrValue";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @NotNull
+    private JPAAPlainAttr attribute;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public APlainAttr getAttr() {
+        return attribute;
+    }
+
+    @Override
+    public void setAttr(final PlainAttr attr) {
+        checkType(attr, JPAAPlainAttr.class);
+        this.attribute = (JPAAPlainAttr) attr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java
new file mode 100644
index 0000000..93a7941
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java
@@ -0,0 +1,76 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+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.jpa.entity.AbstractEntity;
+
+@Entity
+@Table(name = JPAARelationship.TABLE)
+public class JPAARelationship extends AbstractEntity<Long> implements ARelationship {
+
+    private static final long serialVersionUID = 6608821135023815357L;
+
+    public static final String TABLE = "ARelationship";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @Column(name = "left_anyObject_id")
+    private JPAAnyObject leftEnd;
+
+    @ManyToOne
+    @Column(name = "right_anyObject_id")
+    private JPAAnyObject rightEnd;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public AnyObject getLeftEnd() {
+        return leftEnd;
+    }
+
+    @Override
+    public void setLeftEnd(final AnyObject leftEnd) {
+        checkType(leftEnd, JPAAnyObject.class);
+        this.leftEnd = (JPAAnyObject) leftEnd;
+    }
+
+    @Override
+    public AnyObject getRightEnd() {
+        return rightEnd;
+    }
+
+    @Override
+    public void setRightEnd(final AnyObject rightEnd) {
+        checkType(rightEnd, JPAAnyObject.class);
+        this.rightEnd = (JPAAnyObject) rightEnd;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAVirAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAVirAttr.java
new file mode 100644
index 0000000..7469799
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAVirAttr.java
@@ -0,0 +1,50 @@
+/*
+ * 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.anyobject;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AVirAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
+
+@Entity
+@Table(name = JPAAVirAttr.TABLE)
+public class JPAAVirAttr extends AbstractVirAttr<AnyObject> implements AVirAttr {
+
+    private static final long serialVersionUID = -4935990254545760827L;
+
+    public static final String TABLE = "AVirAttr";
+
+    @ManyToOne
+    private JPAAnyObject owner;
+
+    @Override
+    public AnyObject getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final AnyObject owner) {
+        checkType(owner, JPAAnyObject.class);
+        this.owner = (JPAAnyObject) owner;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..6442c2d
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -0,0 +1,243 @@
+/*
+ * 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.anyobject;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.Valid;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+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.anyobject.ADerAttr;
+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.AVirAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractAny;
+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;
+
+@Entity
+@Table(name = JPAAnyObject.TABLE)
+@Cacheable
+public class JPAAnyObject extends AbstractAny<APlainAttr, ADerAttr, AVirAttr> implements AnyObject {
+
+    private static final long serialVersionUID = 9063766472970643492L;
+
+    public static final String TABLE = "AnyObject";
+
+    @Id
+    private Long id;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPAAnyType type;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAAPlainAttr> plainAttrs = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAADerAttr> derAttrs = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAAVirAttr> virAttrs = new ArrayList<>();
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyObject_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "resource_name"))
+    private List<JPAExternalResource> resources = new ArrayList<>();
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "anyObject_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyTypeClass_name"))
+    private List<JPAAnyTypeClass> auxClasses = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd")
+    @Valid
+    private List<JPAARelationship> relationships = new ArrayList<>();
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd")
+    @Valid
+    private List<JPAAMembership> memberships = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public AnyType getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(final AnyType type) {
+        checkType(type, JPAAnyType.class);
+        this.type = (JPAAnyType) type;
+    }
+
+    @Override
+    public boolean add(final APlainAttr attr) {
+        checkType(attr, JPAAPlainAttr.class);
+        return plainAttrs.add((JPAAPlainAttr) attr);
+    }
+
+    @Override
+    public boolean remove(final APlainAttr attr) {
+        checkType(attr, JPAAPlainAttr.class);
+        return plainAttrs.remove((JPAAPlainAttr) attr);
+    }
+
+    @Override
+    public List<? extends APlainAttr> getPlainAttrs() {
+        return plainAttrs;
+    }
+
+    @Override
+    public boolean add(final ADerAttr attr) {
+        checkType(attr, JPAADerAttr.class);
+        return derAttrs.add((JPAADerAttr) attr);
+    }
+
+    @Override
+    public boolean remove(final ADerAttr attr) {
+        checkType(attr, JPAADerAttr.class);
+        return derAttrs.remove((JPAADerAttr) attr);
+    }
+
+    @Override
+    public List<? extends ADerAttr> getDerAttrs() {
+        return derAttrs;
+    }
+
+    @Override
+    public boolean add(final AVirAttr attr) {
+        checkType(attr, JPAAVirAttr.class);
+        return virAttrs.add((JPAAVirAttr) attr);
+    }
+
+    @Override
+    public boolean remove(final AVirAttr attr) {
+        checkType(attr, JPAAVirAttr.class);
+        return virAttrs.remove((JPAAVirAttr) attr);
+    }
+
+    @Override
+    public List<? extends AVirAttr> getVirAttrs() {
+        return virAttrs;
+    }
+
+    @Override
+    protected List<JPAExternalResource> internalGetResources() {
+        return resources;
+    }
+
+    @Override
+    public boolean add(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.add((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getAuxClasses() {
+        return auxClasses;
+    }
+
+    @Override
+    public boolean add(final ARelationship relationship) {
+        checkType(relationship, JPAARelationship.class);
+        return this.relationships.add((JPAARelationship) relationship);
+    }
+
+    @Override
+    public boolean remove(final ARelationship relationship) {
+        checkType(relationship, JPAARelationship.class);
+        return this.relationships.remove((JPAARelationship) relationship);
+    }
+
+    @Override
+    public ARelationship getRelationship(final AnyObject rightEnd) {
+        return CollectionUtils.find(getRelationships(), new Predicate<ARelationship>() {
+
+            @Override
+            public boolean evaluate(final ARelationship relationship) {
+                return rightEnd != null && rightEnd.equals(relationship.getRightEnd());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends ARelationship> getRelationships() {
+        return relationships;
+    }
+
+    @Override
+    public boolean add(final AMembership membership) {
+        checkType(membership, JPAAMembership.class);
+        return this.memberships.add((JPAAMembership) membership);
+    }
+
+    @Override
+    public boolean remove(final AMembership membership) {
+        checkType(membership, JPAAMembership.class);
+        return this.memberships.remove((JPAAMembership) membership);
+    }
+
+    @Override
+    public AMembership getMembership(final Long groupKey) {
+        return CollectionUtils.find(getMemberships(), new Predicate<AMembership>() {
+
+            @Override
+            public boolean evaluate(final AMembership membership) {
+                return groupKey != null && groupKey.equals(membership.getRightEnd().getKey());
+            }
+        });
+    }
+
+    @Override
+    public List<? extends AMembership> getMemberships() {
+        return memberships;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
index 20e8d68..6fd6c1e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttr.java
@@ -24,20 +24,16 @@ import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.Valid;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 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.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.Conf;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
 
@@ -46,7 +42,7 @@ import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
  */
 @Entity
 @Table(name = JPACPlainAttr.TABLE)
-public class JPACPlainAttr extends AbstractPlainAttr implements CPlainAttr {
+public class JPACPlainAttr extends AbstractPlainAttr<Conf> implements CPlainAttr {
 
     private static final long serialVersionUID = 8022331942314540648L;
 
@@ -65,18 +61,11 @@ public class JPACPlainAttr extends AbstractPlainAttr implements CPlainAttr {
     private JPAConf owner;
 
     /**
-     * The schema of this attribute.
-     */
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = "schema_name")
-    private JPACPlainSchema schema;
-
-    /**
      * Values of this attribute (if schema is not UNIQUE).
      */
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
-    private List<JPACPlainAttrValue> values;
+    private List<JPACPlainAttrValue> values = new ArrayList<>();
 
     /**
      * Value of this attribute (if schema is UNIQUE).
@@ -85,14 +74,6 @@ public class JPACPlainAttr extends AbstractPlainAttr implements CPlainAttr {
     @Valid
     private JPACPlainAttrUniqueValue uniqueValue;
 
-    /**
-     * Default constructor.
-     */
-    public JPACPlainAttr() {
-        super();
-        values = new ArrayList<>();
-    }
-
     @Override
     public Long getKey() {
         return id;
@@ -104,30 +85,19 @@ public class JPACPlainAttr extends AbstractPlainAttr implements CPlainAttr {
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final Conf owner) {
         checkType(owner, JPAConf.class);
         this.owner = (JPAConf) owner;
     }
 
     @Override
-    public CPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPACPlainSchema.class);
-        this.schema = (JPACPlainSchema) schema;
-    }
-
-    @Override
-    protected boolean addValue(final PlainAttrValue attrValue) {
+    protected boolean addForMultiValue(final PlainAttrValue attrValue) {
         checkType(attrValue, JPACPlainAttrValue.class);
         return values.add((JPACPlainAttrValue) attrValue);
     }
 
     @Override
-    public boolean removeValue(final PlainAttrValue attrValue) {
+    public boolean remove(final PlainAttrValue attrValue) {
         checkType(attrValue, JPACPlainAttrValue.class);
         return values.remove((JPACPlainAttrValue) attrValue);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttrUniqueValue.java
index 097a046..4783911 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttrUniqueValue.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainAttrUniqueValue.java
@@ -28,8 +28,8 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 
 @Entity
 @Table(name = JPACPlainAttrUniqueValue.TABLE)
@@ -47,7 +47,7 @@ public class JPACPlainAttrUniqueValue extends AbstractPlainAttrValue implements
 
     @ManyToOne(optional = false)
     @JoinColumn(name = "schema_name")
-    private JPACPlainSchema schema;
+    private JPAPlainSchema schema;
 
     @Override
     public Long getKey() {
@@ -66,13 +66,13 @@ public class JPACPlainAttrUniqueValue extends AbstractPlainAttrValue implements
     }
 
     @Override
-    public CPlainSchema getSchema() {
+    public PlainSchema getSchema() {
         return schema;
     }
 
     @Override
     public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPACPlainSchema.class);
-        this.schema = (JPACPlainSchema) schema;
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainSchema.java
deleted file mode 100644
index 590443b..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPACPlainSchema.java
+++ /dev/null
@@ -1,36 +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.conf;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
-
-@Entity
-@Table(name = JPACPlainSchema.TABLE)
-@Cacheable
-public class JPACPlainSchema extends AbstractPlainSchema implements CPlainSchema {
-
-    private static final long serialVersionUID = 3363019039331594433L;
-
-    public static final String TABLE = "CPlainSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
index 13e529f..be3fa19 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java
@@ -28,16 +28,22 @@ import javax.persistence.Id;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import javax.validation.Valid;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+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.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.Conf;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractAttributable;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractAnnotatedEntity;
 
 @Entity
 @Table(name = JPAConf.TABLE)
 @Cacheable
-public class JPAConf extends AbstractAttributable<CPlainAttr, DerAttr, VirAttr> implements Conf {
+public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
 
     private static final long serialVersionUID = 7671699609879382195L;
 
@@ -67,50 +73,147 @@ public class JPAConf extends AbstractAttributable<CPlainAttr, DerAttr, VirAttr>
     }
 
     @Override
-    public boolean addPlainAttr(final CPlainAttr attr) {
+    public boolean add(final CPlainAttr attr) {
         checkType(attr, JPACPlainAttr.class);
         return plainAttrs.add((JPACPlainAttr) attr);
     }
 
     @Override
-    public boolean removePlainAttr(final CPlainAttr attr) {
+    public boolean remove(final CPlainAttr attr) {
         checkType(attr, JPACPlainAttr.class);
         return plainAttrs.remove((JPACPlainAttr) attr);
     }
 
     @Override
+    public CPlainAttr getPlainAttr(final String plainSchemaName) {
+        return CollectionUtils.find(plainAttrs, new Predicate<CPlainAttr>() {
+
+            @Override
+            public boolean evaluate(final CPlainAttr plainAttr) {
+                return plainAttr != null && plainAttr.getSchema() != null
+                        && plainSchemaName.equals(plainAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    @Override
     public List<? extends CPlainAttr> getPlainAttrs() {
         return plainAttrs;
     }
 
     @Override
-    public boolean addDerAttr(final DerAttr attr) {
+    public boolean add(final DerAttr<?> attr) {
         return false;
     }
 
     @Override
-    public boolean removeDerAttr(final DerAttr derAttr) {
+    public boolean remove(final DerAttr<?> derAttr) {
         return false;
     }
 
     @Override
-    public List<? extends DerAttr> getDerAttrs() {
+    public DerAttr<?> getDerAttr(final String derSchemaName) {
+        return null;
+    }
+
+    @Override
+    public List<? extends DerAttr<?>> getDerAttrs() {
         return Collections.emptyList();
     }
 
     @Override
-    public boolean addVirAttr(final VirAttr attr) {
+    public boolean add(final VirAttr<?> attr) {
         return false;
     }
 
     @Override
-    public boolean removeVirAttr(final VirAttr virAttr) {
+    public boolean remove(final VirAttr<?> virAttr) {
         return false;
     }
 
     @Override
-    public List<? extends VirAttr> getVirAttrs() {
+    public VirAttr<?> getVirAttr(final String virSchemaName) {
+        return null;
+    }
+
+    @Override
+    public List<? extends VirAttr<?>> getVirAttrs() {
         return Collections.emptyList();
     }
 
+    @Override
+    public boolean add(final ExternalResource resource) {
+        return false;
+    }
+
+    @Override
+    public boolean remove(final ExternalResource resource) {
+        return false;
+    }
+
+    @Override
+    public List<String> getResourceNames() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<? extends ExternalResource> getResources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean add(final AnyTypeClass auxClass) {
+        return false;
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass auxClass) {
+        return false;
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getAuxClasses() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getWorkflowId() {
+        return null;
+    }
+
+    @Override
+    public void setWorkflowId(final String workflowId) {
+        // nothing to do
+    }
+
+    @Override
+    public String getStatus() {
+        return null;
+    }
+
+    @Override
+    public void setStatus(final String status) {
+        // nothing to do
+    }
+
+    @Override
+    public Realm getRealm() {
+        return null;
+    }
+
+    @Override
+    public void setRealm(final Realm realm) {
+        // nothing to do
+    }
+
+    @Override
+    public AnyType getType() {
+        return null;
+    }
+
+    @Override
+    public void setType(final AnyType type) {
+        // nothing to do
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttr.java
index 7a160cf..46fc1cd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttr.java
@@ -18,23 +18,16 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.group;
 
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
 
 @Entity
 @Table(name = JPAGDerAttr.TABLE)
-public class JPAGDerAttr extends AbstractDerAttr implements GDerAttr {
+public class JPAGDerAttr extends AbstractDerAttr<Group> implements GDerAttr {
 
     private static final long serialVersionUID = 8007080005675899946L;
 
@@ -43,40 +36,15 @@ public class JPAGDerAttr extends AbstractDerAttr implements GDerAttr {
     @ManyToOne
     private JPAGroup owner;
 
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAGDerAttrTemplate template;
-
     @Override
     public Group getOwner() {
         return owner;
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final Group owner) {
         checkType(owner, JPAGroup.class);
         this.owner = (JPAGroup) owner;
     }
 
-    @Override
-    public GDerAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final GDerAttrTemplate template) {
-        checkType(template, JPAGDerAttrTemplate.class);
-        this.template = (JPAGDerAttrTemplate) template;
-    }
-
-    @Override
-    public GDerSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final DerSchema schema) {
-        LOG.warn("This is group attribute, set template to select schema");
-    }
-
 }


[22/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/APlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/APlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/APlainAttr.java
new file mode 100644
index 0000000..46d2297
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/APlainAttr.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.anyobject;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+
+public interface APlainAttr extends PlainAttr<AnyObject> {
+
+    @Override
+    List<? extends APlainAttrValue> getValues();
+
+    @Override
+    APlainAttrUniqueValue getUniqueValue();
+
+}

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

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

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
new file mode 100644
index 0000000..ddb047e
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.anyobject;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Any;
+
+public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
+
+    boolean add(ARelationship relationship);
+
+    boolean remove(ARelationship relationship);
+
+    ARelationship getRelationship(AnyObject rightEnd);
+
+    List<? extends ARelationship> getRelationships();
+
+    boolean add(AMembership membership);
+
+    boolean remove(AMembership membership);
+
+    AMembership getMembership(Long groupKey);
+
+    List<? extends AMembership> getMemberships();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttr.java
index 852f81b..a205b32 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttr.java
@@ -21,14 +21,7 @@ package org.apache.syncope.core.persistence.api.entity.conf;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 
-public interface CPlainAttr extends PlainAttr {
-
-    @SuppressWarnings("unchecked")
-    @Override
-    Conf getOwner();
-
-    @Override
-    CPlainSchema getSchema();
+public interface CPlainAttr extends PlainAttr<Conf> {
 
     @Override
     List<? extends CPlainAttrValue> getValues();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttrUniqueValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttrUniqueValue.java
index 6e1277c..9b82e00 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttrUniqueValue.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/CPlainAttrUniqueValue.java
@@ -25,7 +25,4 @@ public interface CPlainAttrUniqueValue extends PlainAttrUniqueValue {
     @Override
     CPlainAttr getAttr();
 
-    @Override
-    CPlainSchema getSchema();
-
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
index b40cd39..2b6e424 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/conf/Conf.java
@@ -19,19 +19,19 @@
 package org.apache.syncope.core.persistence.api.entity.conf;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 
-public interface Conf extends Attributable<CPlainAttr, DerAttr, VirAttr> {
+public interface Conf extends Any<CPlainAttr, DerAttr<?>, VirAttr<?>> {
 
     void setKey(Long key);
 
     @Override
-    boolean addPlainAttr(CPlainAttr attr);
+    boolean add(CPlainAttr attr);
 
     @Override
-    boolean removePlainAttr(CPlainAttr attr);
+    boolean remove(CPlainAttr attr);
 
     @Override
     List<? extends CPlainAttr> getPlainAttrs();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GDerAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GDerAttr.java
index 59e665f..04d1f85 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GDerAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GDerAttr.java
@@ -20,15 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.group;
 
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 
-public interface GDerAttr extends DerAttr {
+public interface GDerAttr extends DerAttr<Group> {
 
-    @Override
-    Group getOwner();
-
-    @Override
-    GDerSchema getSchema();
-
-    GDerAttrTemplate getTemplate();
-
-    void setTemplate(GDerAttrTemplate template);
 }

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

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

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttr.java
index cf3f551..05bad88 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttr.java
@@ -21,17 +21,7 @@ package org.apache.syncope.core.persistence.api.entity.group;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 
-public interface GPlainAttr extends PlainAttr {
-
-    @Override
-    Group getOwner();
-
-    @Override
-    GPlainSchema getSchema();
-
-    GPlainAttrTemplate getTemplate();
-
-    void setTemplate(GPlainAttrTemplate template);
+public interface GPlainAttr extends PlainAttr<Group> {
 
     @Override
     List<? extends GPlainAttrValue> getValues();

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttrUniqueValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttrUniqueValue.java
index 2ce9285..6fa9abb 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttrUniqueValue.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GPlainAttrUniqueValue.java
@@ -25,7 +25,4 @@ public interface GPlainAttrUniqueValue extends PlainAttrUniqueValue {
     @Override
     GPlainAttr getAttr();
 
-    @Override
-    GPlainSchema getSchema();
-
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
index 9ef9f4a..1847794 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/GVirAttr.java
@@ -20,15 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.group;
 
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 
-public interface GVirAttr extends VirAttr {
+public interface GVirAttr extends VirAttr<Group> {
 
-    @Override
-    Group getOwner();
-
-    @Override
-    GVirSchema getSchema();
-
-    GVirAttrTemplate getTemplate();
-
-    void setTemplate(GVirAttrTemplate template);
 }

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
index f7959cd..cb6008e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
@@ -19,61 +19,55 @@
 package org.apache.syncope.core.persistence.api.entity.group;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
+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.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 
-public interface Group extends Subject<GPlainAttr, GDerAttr, GVirAttr> {
+public interface Group extends Any<GPlainAttr, GDerAttr, GVirAttr> {
 
     String getName();
 
-    <T extends AttrTemplate<K>, K extends Schema> T getAttrTemplate(Class<T> reference, String schemaName);
-
-    <T extends AttrTemplate<K>, K extends Schema> List<K> getAttrTemplateSchemas(Class<T> reference);
-
-    <T extends AttrTemplate<K>, K extends Schema> List<T> getAttrTemplates(Class<T> reference);
+    void setName(String name);
 
     Group getGroupOwner();
 
     User getUserOwner();
 
-    void setName(String name);
-
     void setGroupOwner(Group groupOwner);
 
     void setUserOwner(User userOwner);
 
     @Override
-    boolean addPlainAttr(GPlainAttr attr);
+    boolean add(GPlainAttr attr);
 
     @Override
-    boolean removePlainAttr(GPlainAttr attr);
+    boolean remove(GPlainAttr attr);
 
     @Override
-    boolean addDerAttr(GDerAttr attr);
+    GPlainAttr getPlainAttr(String plainSchemaName);
 
     @Override
-    boolean removeDerAttr(GDerAttr derAttr);
+    List<? extends GPlainAttr> getPlainAttrs();
 
     @Override
-    boolean addVirAttr(GVirAttr attr);
+    boolean add(GDerAttr attr);
 
     @Override
-    boolean removeVirAttr(GVirAttr virAttr);
+    boolean remove(GDerAttr derAttr);
 
     @Override
-    GPlainAttr getPlainAttr(String plainSchemaName);
+    GDerAttr getDerAttr(String derSchemaName);
 
     @Override
-    List<? extends GPlainAttr> getPlainAttrs();
+    List<? extends GDerAttr> getDerAttrs();
 
     @Override
-    GDerAttr getDerAttr(String derSchemaName);
+    boolean add(GVirAttr attr);
 
     @Override
-    List<? extends GDerAttr> getDerAttrs();
+    boolean remove(GVirAttr virAttr);
 
     @Override
     GVirAttr getVirAttr(String virSchemaName);
@@ -81,7 +75,19 @@ public interface Group extends Subject<GPlainAttr, GDerAttr, GVirAttr> {
     @Override
     List<? extends GVirAttr> getVirAttrs();
 
-    DynGroupMembership getDynMembership();
+    ADynGroupMembership getADynMembership();
+
+    void setADynMembership(ADynGroupMembership aDynMembership);
+
+    UDynGroupMembership getUDynMembership();
+
+    void setUDynMembership(UDynGroupMembership uDynMembership);
+
+    boolean add(TypeExtension typeExtension);
+
+    boolean remove(TypeExtension typeExtension);
+
+    TypeExtension getTypeExtension(AnyType anyType);
 
-    void setDynMembership(DynGroupMembership dynMembership);
+    List<? extends TypeExtension> getTypeExtensions();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
new file mode 100644
index 0000000..a426146
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/TypeExtension.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity.group;
+
+import 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;
+
+public interface TypeExtension extends Entity<Long> {
+
+    Group getGroup();
+
+    void setGroup(Group group);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
+
+    boolean add(AnyTypeClass anyTypeClass);
+
+    boolean remove(AnyTypeClass anyTypeClass);
+
+    List<? extends AnyTypeClass> getAuxClasses();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MDerAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MDerAttr.java
deleted file mode 100644
index c55ab68..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MDerAttr.java
+++ /dev/null
@@ -1,34 +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.membership;
-
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-
-public interface MDerAttr extends DerAttr {
-
-    @Override
-    Membership getOwner();
-
-    @Override
-    MDerSchema getSchema();
-
-    MDerAttrTemplate getTemplate();
-
-    void setTemplate(MDerAttrTemplate template);
-}

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttr.java
deleted file mode 100644
index ede83d0..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttr.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.membership;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-
-public interface MPlainAttr extends PlainAttr {
-
-    @Override
-    Membership getOwner();
-
-    @Override
-    MPlainSchema getSchema();
-
-    MPlainAttrTemplate getTemplate();
-
-    void setTemplate(MPlainAttrTemplate template);
-
-    @Override
-    List<? extends MPlainAttrValue> getValues();
-
-    @Override
-    MPlainAttrUniqueValue getUniqueValue();
-
-}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrUniqueValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrUniqueValue.java
deleted file mode 100644
index f77f9ff..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrUniqueValue.java
+++ /dev/null
@@ -1,31 +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.membership;
-
-import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
-
-public interface MPlainAttrUniqueValue extends PlainAttrUniqueValue {
-
-    @Override
-    MPlainAttr getAttr();
-
-    @Override
-    MPlainSchema getSchema();
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrValue.java
deleted file mode 100644
index b92f2fb..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MPlainAttrValue.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.membership;
-
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-
-public interface MPlainAttrValue extends PlainAttrValue {
-
-    @Override
-    MPlainAttr getAttr();
-
-}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MVirAttr.java
deleted file mode 100644
index f710ea6..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/MVirAttr.java
+++ /dev/null
@@ -1,34 +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.membership;
-
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public interface MVirAttr extends VirAttr {
-
-    @Override
-    Membership getOwner();
-
-    @Override
-    MVirSchema getSchema();
-
-    MVirAttrTemplate getTemplate();
-
-    void setTemplate(MVirAttrTemplate template);
-}

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/Membership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/Membership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/Membership.java
deleted file mode 100644
index b83270a..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/membership/Membership.java
+++ /dev/null
@@ -1,53 +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.membership;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-
-public interface Membership extends Attributable<MPlainAttr, MDerAttr, MVirAttr> {
-
-    Group getGroup();
-
-    User getUser();
-
-    void setGroup(Group group);
-
-    void setUser(User user);
-
-    @Override
-    MPlainAttr getPlainAttr(String plainSchemaName);
-
-    @Override
-    List<? extends MPlainAttr> getPlainAttrs();
-
-    @Override
-    MDerAttr getDerAttr(String derSchemaName);
-
-    @Override
-    List<? extends MDerAttr> getDerAttrs();
-
-    @Override
-    MVirAttr getVirAttr(String virSchemaName);
-
-    @Override
-    List<? extends MVirAttr> getVirAttrs();
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
----------------------------------------------------------------------
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/resource/ExternalResource.java
new file mode 100644
index 0000000..da545e4
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -0,0 +1,106 @@
+/*
+ * 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.Set;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
+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.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+
+public interface ExternalResource extends AnnotatedEntity<String> {
+
+    void setKey(String name);
+
+    ConnInstance getConnector();
+
+    void setConnector(ConnInstance connector);
+
+    Set<ConnConfProperty> getConnInstanceConfiguration();
+
+    void setConnInstanceConfiguration(Set<ConnConfProperty> properties);
+
+    AccountPolicy getAccountPolicy();
+
+    void setAccountPolicy(AccountPolicy accountPolicy);
+
+    PasswordPolicy getPasswordPolicy();
+
+    void setPasswordPolicy(PasswordPolicy passwordPolicy);
+
+    SyncPolicy getSyncPolicy();
+
+    void setSyncPolicy(SyncPolicy syncPolicy);
+
+    TraceLevel getCreateTraceLevel();
+
+    void setCreateTraceLevel(TraceLevel createTraceLevel);
+
+    TraceLevel getUpdateTraceLevel();
+
+    void setUpdateTraceLevel(TraceLevel updateTraceLevel);
+
+    TraceLevel getDeleteTraceLevel();
+
+    void setDeleteTraceLevel(TraceLevel deleteTraceLevel);
+
+    TraceLevel getSyncTraceLevel();
+
+    void setSyncTraceLevel(TraceLevel syncTraceLevel);
+
+    List<String> getPropagationActionsClassNames();
+
+    PropagationMode getPropagationMode();
+
+    void setPropagationMode(PropagationMode propagationMode);
+
+    Integer getPropagationPriority();
+
+    void setPropagationPriority(Integer priority);
+
+    boolean isEnforceMandatoryCondition();
+
+    void setEnforceMandatoryCondition(boolean enforce);
+
+    boolean isPropagationPrimary();
+
+    void setPropagationPrimary(boolean condition);
+
+    boolean isRandomPwdIfNotProvided();
+
+    void setRandomPwdIfNotProvided(boolean condition);
+
+    boolean add(Provision provision);
+
+    boolean remove(Provision provision);
+
+    Provision getProvision(AnyType anyType);
+
+    Provision getProvision(ObjectClass objectClass);
+
+    List<? extends Provision> getProvisions();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
new file mode 100644
index 0000000..ea9f165
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Mapping.java
@@ -0,0 +1,43 @@
+/*
+ * 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.Entity;
+
+public interface Mapping extends Entity<Long> {
+
+    Provision getProvision();
+
+    void setProvision(Provision provision);
+
+    boolean add(MappingItem item);
+
+    boolean remove(MappingItem item);
+
+    MappingItem getConnObjectKeyItem();
+
+    void setConnObjectKeyItem(MappingItem item);
+
+    String getConnObjectLink();
+
+    void setConnObjectLink(String connObjectLink);
+
+    List<? extends MappingItem> getItems();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
new file mode 100644
index 0000000..1a5380f
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/MappingItem.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public interface MappingItem extends Entity<Long> {
+
+    Mapping getMapping();
+
+    void setMapping(Mapping mapping);
+
+    String getExtAttrName();
+
+    void setExtAttrName(String extAttrName);
+
+    String getIntAttrName();
+
+    void setIntAttrName(String intAttrName);
+
+    IntMappingType getIntMappingType();
+
+    void setIntMappingType(IntMappingType intMappingType);
+
+    String getMandatoryCondition();
+
+    void setMandatoryCondition(String condition);
+
+    MappingPurpose getPurpose();
+
+    void setPurpose(MappingPurpose purpose);
+
+    boolean isConnObjectKey();
+
+    void setConnObjectKey(boolean connObjectKey);
+
+    boolean isPassword();
+
+    void setPassword(boolean password);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..f1b33fe
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/Provision.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.syncope.core.persistence.api.entity.AnyType;
+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 Provision extends Entity<Long> {
+
+    ExternalResource getResource();
+
+    void setResource(ExternalResource resource);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
+
+    ObjectClass getObjectClass();
+
+    void setObjectClass(ObjectClass objectClass);
+
+    SyncToken getSyncToken();
+
+    String getSerializedSyncToken();
+
+    void setSyncToken(SyncToken syncToken);
+
+    Mapping getMapping();
+
+    void setMapping(Mapping mapping);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyFilter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyFilter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyFilter.java
new file mode 100644
index 0000000..8ae4472
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyFilter.java
@@ -0,0 +1,37 @@
+/*
+ * 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.task;
+
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public interface AnyFilter extends Entity<Long> {
+
+    PushTask getPushTask();
+
+    void setPushTask(PushTask pushTask);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
+
+    String get();
+
+    void set(String filter);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplate.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplate.java
new file mode 100644
index 0000000..fa43dc3
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/AnyTemplate.java
@@ -0,0 +1,38 @@
+/*
+ * 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.task;
+
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public interface AnyTemplate extends Entity<Long> {
+
+    SyncTask getSyncTask();
+
+    void setSyncTask(SyncTask syncTask);
+
+    AnyType getAnyType();
+
+    void setAnyType(AnyType anyType);
+
+    AnyTO get();
+
+    void set(AnyTO template);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PropagationTask.java
index 04bea51..7629074 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
@@ -19,47 +19,47 @@
 package org.apache.syncope.core.persistence.api.entity.task;
 
 import java.util.Set;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.identityconnectors.framework.common.objects.Attribute;
 
 public interface PropagationTask extends Task {
 
-    String getAccountId();
+    String getConnObjectKey();
 
-    Set<Attribute> getAttributes();
+    void setConnObjectKey(String connObjectKey);
 
-    String getObjectClassName();
+    String getOldConnObjectKey();
 
-    String getOldAccountId();
+    void setOldConnObjectKey(String oldConnObjectKey);
 
-    PropagationMode getPropagationMode();
+    Set<Attribute> getAttributes();
 
-    ResourceOperation getPropagationOperation();
+    void setAttributes(Set<Attribute> attributes);
 
-    ExternalResource getResource();
+    String getObjectClassName();
 
-    Long getSubjectKey();
+    void setObjectClassName(String objectClassName);
 
-    AttributableType getSubjectType();
+    PropagationMode getPropagationMode();
 
-    void setAccountId(String accountId);
+    void setPropagationMode(PropagationMode propagationMode);
 
-    void setAttributes(Set<Attribute> attributes);
+    ResourceOperation getPropagationOperation();
 
-    void setObjectClassName(String objectClassName);
+    void setPropagationOperation(ResourceOperation operation);
 
-    void setOldAccountId(String oldAccountId);
+    Long getAnyKey();
 
-    void setPropagationMode(PropagationMode propagationMode);
+    void setAnyKey(Long anyKey);
 
-    void setPropagationOperation(ResourceOperation operation);
+    AnyTypeKind getAnyTypeKind();
 
-    void setResource(ExternalResource resource);
+    void setAnyTypeKind(AnyTypeKind anyTypeKind);
 
-    void setSubjectKey(Long subjectKey);
+    ExternalResource getResource();
 
-    void setSubjectType(AttributableType subjectType);
+    void setResource(ExternalResource resource);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/ProvisioningTask.java
----------------------------------------------------------------------
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 a0e8047..e1b9a5e 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,38 +21,38 @@ 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.resource.ExternalResource;
 
 public interface ProvisioningTask extends SchedTask {
 
+    ExternalResource getResource();
+
+    void setResource(ExternalResource resource);
+
     List<String> getActionsClassNames();
 
     MatchingRule getMatchingRule();
 
-    ExternalResource getResource();
+    void setMatchingRule(MatchingRule matchigRule);
 
     UnmatchingRule getUnmatchingRule();
 
-    boolean isPerformCreate();
-
-    boolean isPerformDelete();
-
-    boolean isPerformUpdate();
-
-    boolean isSyncStatus();
+    void setUnmatchingRule(UnmatchingRule unmatchigRule);
 
-    void setMatchingRule(MatchingRule matchigRule);
+    boolean isPerformCreate();
 
     void setPerformCreate(boolean performCreate);
 
+    boolean isPerformDelete();
+
     void setPerformDelete(boolean performDelete);
 
+    boolean isPerformUpdate();
+
     void setPerformUpdate(boolean performUpdate);
 
-    void setResource(ExternalResource resource);
+    boolean isSyncStatus();
 
     void setSyncStatus(boolean syncStatus);
 
-    void setUnmatchingRule(UnmatchingRule unmatchigRule);
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
index deaf36f..1de3209 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/PushTask.java
@@ -18,13 +18,16 @@
  */
 package org.apache.syncope.core.persistence.api.entity.task;
 
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+
 public interface PushTask extends ProvisioningTask {
 
-    String getGroupFilter();
+    boolean add(AnyFilter filter);
 
-    String getUserFilter();
+    boolean remove(AnyFilter filter);
 
-    void setGroupFilter(String filter);
+    AnyFilter getFilter(AnyType anyType);
 
-    void setUserFilter(String filter);
+    List<? extends AnyFilter> getFilters();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
index 600ef88..7550ed8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
@@ -18,25 +18,25 @@
  */
 package org.apache.syncope.core.persistence.api.entity.task;
 
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 
 public interface SyncTask extends ProvisioningTask {
 
     Realm getDestinatioRealm();
 
-    GroupTO getGroupTemplate();
-
-    UserTO getUserTemplate();
+    void setDestinationRealm(Realm destinationRealm);
 
     boolean isFullReconciliation();
 
     void setFullReconciliation(boolean condition);
 
-    void setGroupTemplate(GroupTO groupTemplate);
+    boolean add(AnyTemplate template);
 
-    void setUserTemplate(UserTO userTemplate);
+    boolean remove(AnyTemplate template);
 
-    void setDestinationRealm(Realm destinationRealm);
+    AnyTemplate getTemplate(AnyType anyType);
+
+    List<? extends AnyTemplate> getTemplates();
 }


[02/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
index 5f317ed..e77f343 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PlainSchemaITCase.java
@@ -29,14 +29,13 @@ import java.security.AccessControlException;
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.syncope.common.lib.AttributableOperations;
+import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
@@ -61,10 +60,10 @@ public class PlainSchemaITCase extends AbstractITCase {
         PlainSchemaTO schemaTO = buildPlainSchemaTO("testAttribute", AttrSchemaType.String);
         schemaTO.setMandatoryCondition("false");
 
-        PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertEquals(schemaTO, newPlainSchemaTO);
 
-        newPlainSchemaTO = createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+        newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertEquals(schemaTO, newPlainSchemaTO);
     }
 
@@ -75,7 +74,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setType(AttrSchemaType.String);
 
         try {
-            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+            createSchema(SchemaType.PLAIN, schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -92,7 +91,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setType(AttrSchemaType.Enum);
 
         try {
-            createSchema(AttributableType.GROUP, SchemaType.PLAIN, schemaTO);
+            createSchema(SchemaType.PLAIN, schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -109,7 +108,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setType(AttrSchemaType.Enum);
 
         try {
-            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+            createSchema(SchemaType.PLAIN, schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -126,7 +125,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
         schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
 
-        createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+        createSchema(SchemaType.PLAIN, schemaTO);
     }
 
     @Test
@@ -136,19 +135,19 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setType(AttrSchemaType.Binary);
         schemaTO.setMimeType("application/x-x509-ca-cert");
 
-        createSchema(AttributableType.GROUP, SchemaType.PLAIN, schemaTO);
+        createSchema(SchemaType.PLAIN, schemaTO);
     }
 
     @Test
     public void delete() {
         PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
         schemaTO.setMandatoryCondition("false");
-        createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        createSchema(SchemaType.PLAIN, schemaTO);
 
-        schemaService.delete(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+        schemaService.delete(SchemaType.PLAIN, schemaTO.getKey());
         PlainSchemaTO firstname = null;
         try {
-            firstname = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+            firstname = schemaService.read(SchemaType.PLAIN, schemaTO.getKey());
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
         }
@@ -157,19 +156,19 @@ public class PlainSchemaITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        List<PlainSchemaTO> userSchemas = schemaService.list(AttributableType.USER, SchemaType.PLAIN);
+        List<PlainSchemaTO> userSchemas = schemaService.list(SchemaType.PLAIN);
         assertFalse(userSchemas.isEmpty());
         for (PlainSchemaTO schemaTO : userSchemas) {
             assertNotNull(schemaTO);
         }
 
-        List<PlainSchemaTO> groupSchemas = schemaService.list(AttributableType.GROUP, SchemaType.PLAIN);
+        List<PlainSchemaTO> groupSchemas = schemaService.list(SchemaType.PLAIN);
         assertFalse(groupSchemas.isEmpty());
         for (PlainSchemaTO schemaTO : groupSchemas) {
             assertNotNull(schemaTO);
         }
 
-        List<PlainSchemaTO> membershipSchemas = schemaService.list(AttributableType.MEMBERSHIP, SchemaType.PLAIN);
+        List<PlainSchemaTO> membershipSchemas = schemaService.list(SchemaType.PLAIN);
         assertFalse(membershipSchemas.isEmpty());
         for (PlainSchemaTO schemaTO : membershipSchemas) {
             assertNotNull(schemaTO);
@@ -178,16 +177,16 @@ public class PlainSchemaITCase extends AbstractITCase {
 
     @Test
     public void update() {
-        PlainSchemaTO schemaTO = schemaService.read(AttributableType.GROUP, SchemaType.PLAIN, "icon");
+        PlainSchemaTO schemaTO = schemaService.read(SchemaType.PLAIN, "icon");
         assertNotNull(schemaTO);
 
-        schemaService.update(AttributableType.GROUP, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
-        PlainSchemaTO updatedTO = schemaService.read(AttributableType.GROUP, SchemaType.PLAIN, "icon");
+        schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+        PlainSchemaTO updatedTO = schemaService.read(SchemaType.PLAIN, "icon");
         assertEquals(schemaTO, updatedTO);
 
         updatedTO.setType(AttrSchemaType.Date);
         try {
-            schemaService.update(AttributableType.GROUP, SchemaType.PLAIN, schemaTO.getKey(), updatedTO);
+            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), updatedTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -200,7 +199,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO.setKey("schema_issue258");
         schemaTO.setType(AttrSchemaType.Double);
 
-        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
         UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
@@ -211,7 +210,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         schemaTO.setType(AttrSchemaType.Long);
         try {
-            schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -223,7 +222,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue259", AttrSchemaType.Double);
         schemaTO.setUniqueConstraint(true);
 
-        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
         UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
@@ -233,10 +232,10 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         UserTO newUserTO = SerializationUtils.clone(userTO);
         MembershipTO membership = new MembershipTO();
-        membership.setGroupKey(2L);
+        membership.setRightKey(2L);
         newUserTO.getMemberships().add(membership);
 
-        UserMod userMod = AttributableOperations.diff(newUserTO, userTO);
+        UserMod userMod = AnyOperations.diff(newUserTO, userTO);
 
         userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
         assertNotNull(userTO);
@@ -247,7 +246,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue260", AttrSchemaType.Double);
         schemaTO.setUniqueConstraint(true);
 
-        schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
         UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
@@ -257,7 +256,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         schemaTO.setUniqueConstraint(false);
         try {
-            schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -266,11 +265,11 @@ public class PlainSchemaITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE323() {
-        PlainSchemaTO actual = schemaService.read(AttributableType.GROUP, SchemaType.PLAIN, "icon");
+        PlainSchemaTO actual = schemaService.read(SchemaType.PLAIN, "icon");
         assertNotNull(actual);
 
         try {
-            createSchema(AttributableType.GROUP, SchemaType.PLAIN, actual);
+            createSchema(SchemaType.PLAIN, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
@@ -279,7 +278,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         actual.setKey(null);
         try {
-            createSchema(AttributableType.GROUP, SchemaType.PLAIN, actual);
+            createSchema(SchemaType.PLAIN, actual);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
@@ -293,7 +292,7 @@ public class PlainSchemaITCase extends AbstractITCase {
                 AttrSchemaType.Double);
 
         try {
-            createSchema(AttributableType.GROUP, SchemaType.PLAIN, schema);
+            createSchema(SchemaType.PLAIN, schema);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -305,13 +304,13 @@ public class PlainSchemaITCase extends AbstractITCase {
     public void anonymous() {
         SchemaService unauthenticated = clientFactory.createAnonymous().getService(SchemaService.class);
         try {
-            unauthenticated.list(AttributableType.USER, SchemaType.VIRTUAL);
+            unauthenticated.list(SchemaType.VIRTUAL);
             fail();
         } catch (AccessControlException e) {
             assertNotNull(e);
         }
 
         SchemaService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(SchemaService.class);
-        assertFalse(anonymous.list(AttributableType.USER, SchemaType.VIRTUAL).isEmpty());
+        assertFalse(anonymous.list(SchemaType.VIRTUAL).isEmpty());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
index 2e526af..df36ac4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
@@ -31,10 +31,12 @@ import org.apache.syncope.common.lib.to.AccountPolicyTO;
 import org.apache.syncope.common.lib.to.PasswordPolicyTO;
 import org.apache.syncope.common.lib.to.SyncPolicyTO;
 import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -45,8 +47,12 @@ public class PolicyITCase extends AbstractITCase {
     private SyncPolicyTO buildSyncPolicyTO() {
         SyncPolicyTO policy = new SyncPolicyTO();
 
+        SyncPolicySpecItem item = new SyncPolicySpecItem();
+        item.setAnyTypeKey(AnyTypeKind.USER.name());
+        item.setJavaRule(TestSyncRule.class.getName());
+
         SyncPolicySpec spec = new SyncPolicySpec();
-        spec.setUserJavaRule(TestSyncRule.class.getName());
+        spec.getItems().add(item);
 
         policy.setSpecification(spec);
         policy.setDescription("Sync policy");
@@ -109,7 +115,8 @@ public class PolicyITCase extends AbstractITCase {
 
         assertNotNull(policyTO);
         assertEquals(PolicyType.SYNC, policyTO.getType());
-        assertEquals(TestSyncRule.class.getName(), policyTO.getSpecification().getUserJavaRule());
+        assertEquals(TestSyncRule.class.getName(),
+                policyTO.getSpecification().getItem(AnyTypeKind.USER.name()).getJavaRule());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index 33ee57a..ef525d5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -40,21 +40,22 @@ import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.TraceLevel;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.TaskService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -93,9 +94,9 @@ public class PushTaskITCase extends AbstractTaskITCase {
         PushTaskTO task = new PushTaskTO();
         task.setName("Test create Push");
         task.setResource(RESOURCE_NAME_WS2);
-        task.setUserFilter(
+        task.getFilters().put(AnyTypeKind.USER.name(),
                 SyncopeClient.getUserSearchConditionBuilder().hasNotResources(RESOURCE_NAME_TESTDB2).query());
-        task.setGroupFilter(
+        task.getFilters().put(AnyTypeKind.GROUP.name(),
                 SyncopeClient.getGroupSearchConditionBuilder().isNotNull("cool").query());
         task.setMatchingRule(MatchingRule.LINK);
 
@@ -107,8 +108,10 @@ public class PushTaskITCase extends AbstractTaskITCase {
         assertNotNull(task);
         assertEquals(task.getKey(), actual.getKey());
         assertEquals(task.getJobClassName(), actual.getJobClassName());
-        assertEquals(task.getUserFilter(), actual.getUserFilter());
-        assertEquals(task.getGroupFilter(), actual.getGroupFilter());
+        assertEquals(task.getFilters().get(AnyTypeKind.USER.name()),
+                actual.getFilters().get(AnyTypeKind.USER.name()));
+        assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()),
+                actual.getFilters().get(AnyTypeKind.GROUP.name()));
         assertEquals(UnmatchingRule.ASSIGN, actual.getUnmatchingRule());
         assertEquals(MatchingRule.LINK, actual.getMatchingRule());
     }
@@ -119,12 +122,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
 
         execSyncTask(23L, 50, false);
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, 3L));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertTrue(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
 
         execSyncTask(23L, 50, false);
 
-        assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.GROUP, 3L));
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
     }
 
@@ -249,12 +252,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE598() {
         // create a new group schema
-        final PlainSchemaTO schemaTO = new PlainSchemaTO();
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
         schemaTO.setKey("LDAPGroupName" + getUUIDString());
         schemaTO.setType(AttrSchemaType.String);
         schemaTO.setMandatoryCondition("true");
 
-        final PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.GROUP, SchemaType.PLAIN, schemaTO);
+        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertEquals(schemaTO, newPlainSchemaTO);
 
         // create a new sample group
@@ -262,7 +265,6 @@ public class PushTaskITCase extends AbstractTaskITCase {
         groupTO.setName("all" + getUUIDString());
         groupTO.setRealm("/even");
 
-        groupTO.getGPlainAttrTemplates().add(newPlainSchemaTO.getKey());
         groupTO.getPlainAttrs().add(attrTO(newPlainSchemaTO.getKey(), "all"));
 
         groupTO = createGroup(groupTO);
@@ -277,61 +279,33 @@ public class PushTaskITCase extends AbstractTaskITCase {
             resourceTO.setKey(resourceName);
             resourceTO.setConnectorId(105L);
 
-            final MappingTO umapping = new MappingTO();
-            MappingItemTO item = new MappingItemTO();
-            item.setIntMappingType(IntMappingType.Username);
-            item.setExtAttrName("cn");
-            item.setAccountid(true);
-            item.setPurpose(MappingPurpose.PROPAGATION);
-            item.setMandatoryCondition("true");
-            umapping.setAccountIdItem(item);
-
-            item = new MappingItemTO();
-            item.setIntMappingType(IntMappingType.UserPlainSchema);
-            item.setExtAttrName("surname");
-            item.setIntAttrName("sn");
-            item.setPurpose(MappingPurpose.BOTH);
-            umapping.addItem(item);
-
-            item = new MappingItemTO();
-            item.setIntMappingType(IntMappingType.UserPlainSchema);
-            item.setExtAttrName("email");
-            item.setIntAttrName("mail");
-            item.setPurpose(MappingPurpose.BOTH);
-            umapping.addItem(item);
+            ProvisionTO provisionTO = new ProvisionTO();
+            provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+            provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+            resourceTO.getProvisions().add(provisionTO);
 
-            item = new MappingItemTO();
-            item.setIntMappingType(IntMappingType.Password);
-            item.setPassword(true);
-            item.setPurpose(MappingPurpose.BOTH);
-            item.setMandatoryCondition("true");
-            umapping.addItem(item);
-
-            umapping.setAccountLink("'cn=' + username + ',ou=people,o=isp'");
-
-            final MappingTO rmapping = new MappingTO();
+            MappingTO rmapping = new MappingTO();
+            provisionTO.setMapping(rmapping);
 
-            item = new MappingItemTO();
+            MappingItemTO item = new MappingItemTO();
             item.setIntMappingType(IntMappingType.GroupPlainSchema);
             item.setExtAttrName("cn");
             item.setIntAttrName(newPlainSchemaTO.getKey());
             item.setAccountid(true);
             item.setPurpose(MappingPurpose.BOTH);
-            rmapping.setAccountIdItem(item);
-
-            rmapping.setAccountLink("'cn=' + " + newPlainSchemaTO.getKey() + " + ',ou=groups,o=isp'");
+            rmapping.setConnObjectKeyItem(item);
 
-            resourceTO.setGmapping(rmapping);
+            rmapping.setConnObjectLink("'cn=' + " + newPlainSchemaTO.getKey() + " + ',ou=groups,o=isp'");
 
             Response response = resourceService.create(resourceTO);
             newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
 
             assertNotNull(newResourceTO);
-            assertNull(newResourceTO.getUmapping());
-            assertNotNull(newResourceTO.getGmapping());
+            assertNull(newResourceTO.getProvision(AnyTypeKind.USER.name()));
+            assertNotNull(newResourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping());
 
             // create push task ad-hoc
-            final PushTaskTO task = new PushTaskTO();
+            PushTaskTO task = new PushTaskTO();
             task.setName("issueSYNCOPE598");
             task.setResource(resourceName);
             task.setPerformCreate(true);
@@ -341,12 +315,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
             task.setMatchingRule(MatchingRule.UPDATE);
 
             response = taskService.create(task);
-            final PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+            PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
 
             assertNotNull(push);
 
             // execute the new task
-            final TaskExecTO pushExec = execSyncTask(push.getKey(), 50, false);
+            TaskExecTO pushExec = execSyncTask(push.getKey(), 50, false);
             assertTrue(PropagationTaskExecStatus.valueOf(pushExec.getStatus()).isSuccessful());
         } finally {
             groupService.delete(groupTO.getKey());
@@ -359,12 +333,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE648() {
         //1. Create Push Task
-        final PushTaskTO task = new PushTaskTO();
+        PushTaskTO task = new PushTaskTO();
         task.setName("Test create Push");
         task.setResource(RESOURCE_NAME_LDAP);
-        task.setUserFilter(
+        task.getFilters().put(AnyTypeKind.USER.name(),
                 SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("_NO_ONE_").query());
-        task.setGroupFilter(
+        task.getFilters().put(AnyTypeKind.GROUP.name(),
                 SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("citizen").query());
         task.setMatchingRule(MatchingRule.IGNORE);
         task.setUnmatchingRule(UnmatchingRule.IGNORE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
index 1a014bd..21c3e92 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
@@ -36,7 +36,9 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -44,6 +46,7 @@ import org.apache.syncope.common.lib.types.EntityViolationType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -57,21 +60,27 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
         item = new MappingItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserId);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setExtAttrName("fullname");
@@ -79,9 +88,8 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setAccountid(false);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
-        resourceTO.setUmapping(mapping);
         return resourceTO;
     }
 
@@ -111,14 +119,20 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = "overriding-conn-conf-target-resource-create";
         ResourceTO resourceTO = new ResourceTO();
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setExtAttrName("uid");
         item.setIntAttrName("userId");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
         item = new MappingItemTO();
         item.setExtAttrName("username");
@@ -126,7 +140,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserId);
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setExtAttrName("fullname");
@@ -134,13 +148,11 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setAccountid(false);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
-        resourceTO.setUmapping(mapping);
-
         ConnConfProperty p = new ConnConfProperty();
         ConnConfPropSchema schema = new ConnConfPropSchema();
         schema.setType("java.lang.String");
@@ -149,7 +161,7 @@ public class ResourceITCase extends AbstractITCase {
         p.setSchema(schema);
         p.getValues().add("http://invalidurl/");
 
-        Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<ConnConfProperty>(Arrays.asList(p));
+        Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<>(Arrays.asList(p));
         resourceTO.getConnConfProperties().addAll(connectorConfigurationProperties);
 
         Response response = resourceService.create(resourceTO);
@@ -168,38 +180,47 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
-        MappingTO umapping = new MappingTO();
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
-        umapping.setAccountIdItem(item);
-
-        resourceTO.setUmapping(umapping);
+        mapping.setConnObjectKeyItem(item);
 
-        MappingTO rmapping = new MappingTO();
+        provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+        resourceTO.getProvisions().add(provisionTO);
 
+        mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
         item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.GroupId);
         item.setExtAttrName("groupId");
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.SYNCHRONIZATION);
-        rmapping.setAccountIdItem(item);
-
-        resourceTO.setGmapping(rmapping);
+        mapping.setConnObjectKeyItem(item);
 
         Response response = resourceService.create(resourceTO);
         ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
 
         assertNotNull(actual);
-        assertNotNull(actual.getUmapping());
-        assertNotNull(actual.getUmapping().getItems());
-        assertNotNull(actual.getGmapping());
-        assertNotNull(actual.getGmapping().getItems());
-        assertEquals(MappingPurpose.SYNCHRONIZATION, actual.getGmapping().getAccountIdItem().getPurpose());
-        assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
+        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems());
+        assertEquals(MappingPurpose.SYNCHRONIZATION,
+                actual.getProvision(AnyTypeKind.GROUP.name()).getMapping().getConnObjectKeyItem().getPurpose());
+        assertEquals(MappingPurpose.PROPAGATION,
+                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
     }
 
     @Test
@@ -209,21 +230,25 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
         item.setAccountid(true);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setExtAttrName("email");
         // missing intAttrName ...
-        mapping.addItem(item);
-
-        resourceTO.setUmapping(mapping);
+        mapping.add(item);
 
         try {
             createResource(resourceTO);
@@ -241,21 +266,25 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
         item.setAccountid(true);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setIntAttrName("usernane");
         // missing extAttrName ...
-        mapping.addItem(item);
-
-        resourceTO.setUmapping(mapping);
+        mapping.add(item);
 
         createResource(resourceTO);
     }
@@ -268,7 +297,13 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setConnectorId(102L);
         resourceTO.setPasswordPolicy(4L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setExtAttrName("userId");
@@ -276,9 +311,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
-
-        resourceTO.setUmapping(mapping);
+        mapping.setConnObjectKeyItem(item);
 
         Response response = resourceService.create(resourceTO);
         ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
@@ -311,7 +344,13 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(101L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         // Update with an existing and already assigned mapping
         MappingItemTO item = new MappingItemTO();
@@ -320,7 +359,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
+        mapping.add(item);
 
         // Update defining new mappings
         for (int i = 4; i < 6; i++) {
@@ -329,7 +368,7 @@ public class ResourceITCase extends AbstractITCase {
             item.setIntAttrName("fullname");
             item.setIntMappingType(IntMappingType.UserPlainSchema);
             item.setPurpose(MappingPurpose.BOTH);
-            mapping.addItem(item);
+            mapping.add(item);
         }
         item = new MappingItemTO();
         item.setExtAttrName("username");
@@ -337,16 +376,14 @@ public class ResourceITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserId);
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
-
-        resourceTO.setUmapping(mapping);
+        mapping.setConnObjectKeyItem(item);
 
         resourceService.update(resourceTO.getKey(), resourceTO);
         ResourceTO actual = resourceService.read(resourceTO.getKey());
         assertNotNull(actual);
 
         // check for existence
-        Collection<MappingItemTO> mapItems = actual.getUmapping().getItems();
+        Collection<MappingItemTO> mapItems = actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
         assertNotNull(mapItems);
         assertEquals(4, mapItems.size());
     }
@@ -366,14 +403,15 @@ public class ResourceITCase extends AbstractITCase {
         // create resource with sync token
         String resourceName = RESOURCE_NAME_RESETSYNCTOKEN + getUUIDString();
         ResourceTO pre = buildResourceTO(resourceName);
-        pre.setUsyncToken("test");
+
+        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken("test");
         resourceService.create(pre);
 
-        pre.setUsyncToken(null);
+        pre.getProvision(AnyTypeKind.USER.name()).setSyncToken(null);
         resourceService.update(pre.getKey(), pre);
         ResourceTO actual = resourceService.read(pre.getKey());
         // check that the synctoken has been reset
-        assertNull(actual.getUsyncToken());
+        assertNull(actual.getProvision(AnyTypeKind.USER.name()).getSyncToken());
     }
 
     @Test
@@ -470,14 +508,14 @@ public class ResourceITCase extends AbstractITCase {
 
         ResourceTO resource = resourceService.read(name);
         assertNotNull(resource);
-        assertNotNull(resource.getUmapping());
+        assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
 
-        resource.setUmapping(new MappingTO());
+        resource.getProvision(AnyTypeKind.USER.name()).setMapping(new MappingTO());
         resourceService.update(name, resource);
 
         resource = resourceService.read(name);
         assertNotNull(resource);
-        assertNull(resource.getUmapping());
+        assertNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
     }
 
     @Test
@@ -489,25 +527,29 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(name);
         resourceTO.setConnectorId(105L);
 
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.GROUP.name());
+        provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
         MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.GroupName);
         item.setExtAttrName("cn");
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.GroupOwnerSchema);
         item.setExtAttrName("owner");
         item.setPurpose(MappingPurpose.BOTH);
-        mapping.addItem(item);
-
-        resourceTO.setGmapping(mapping);
+        mapping.add(item);
 
         resourceTO = createResource(resourceTO);
         assertNotNull(resourceTO);
-        assertEquals(2, resourceTO.getGmapping().getItems().size());
+        assertEquals(2, resourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems().size());
     }
 
     @Test
@@ -519,7 +561,7 @@ public class ResourceITCase extends AbstractITCase {
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidExternalResource, e.getType());
 
-            assertTrue(e.getElements().iterator().next().toString().contains(EntityViolationType.InvalidName.name()));
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
         }
     }
 
@@ -546,14 +588,20 @@ public class ResourceITCase extends AbstractITCase {
         resourceTO.setKey(resourceName);
         resourceTO.setConnectorId(102L);
 
-        MappingTO umapping = new MappingTO();
+        ProvisionTO provisionTO = new ProvisionTO();
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
+        resourceTO.getProvisions().add(provisionTO);
+
+        MappingTO mapping = new MappingTO();
+        provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
         item.setAccountid(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
-        umapping.setAccountIdItem(item);
+        mapping.setConnObjectKeyItem(item);
 
         MappingItemTO item2 = new MappingItemTO();
         item2.setIntMappingType(IntMappingType.UserPlainSchema);
@@ -561,18 +609,17 @@ public class ResourceITCase extends AbstractITCase {
         item2.setIntAttrName("gender");
         item2.setExtAttrName("gender");
         item2.setPurpose(MappingPurpose.NONE);
-        umapping.addItem(item2);
-
-        resourceTO.setUmapping(umapping);
+        mapping.add(item2);
 
         Response response = resourceService.create(resourceTO);
         ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
 
         assertNotNull(actual);
-        assertNotNull(actual.getUmapping());
-        assertNotNull(actual.getUmapping().getItems());
-        assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
-        for (MappingItemTO itemTO : actual.getUmapping().getItems()) {
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping());
+        assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems());
+        assertEquals(MappingPurpose.PROPAGATION,
+                actual.getProvision(AnyTypeKind.USER.name()).getMapping().getConnObjectKeyItem().getPurpose());
+        for (MappingItemTO itemTO : actual.getProvision(AnyTypeKind.USER.name()).getMapping().getItems()) {
             if ("gender".equals(itemTO.getIntAttrName())) {
                 assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index 0f56510..02ccb5e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.userService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -29,7 +28,6 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.lib.SyncopeClient;
-import org.apache.syncope.common.lib.CollectionUtils2;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -64,7 +62,7 @@ public class SearchITCase extends AbstractITCase {
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
 
-        Collection<UserTO> found = CollectionUtils2.find(matchedUsers.getResult(), new Predicate<UserTO>() {
+        Collection<UserTO> found = CollectionUtils.select(matchedUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -119,7 +117,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchByDynGroup() {
         GroupTO group = GroupITCase.getBasicSampleTO("dynMembership");
-        group.setDynMembershipCond("cool==true");
+        group.setUDynMembershipCond("cool==true");
         group = createGroup(group);
         assertNotNull(group);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index 27353f0..868deee 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -48,11 +48,12 @@ import org.apache.syncope.common.lib.to.SyncPolicyTO;
 import org.apache.syncope.common.lib.to.SyncTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -108,13 +109,13 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         userTemplate.getResources().add(RESOURCE_NAME_WS2);
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(8L);
+        membershipTO.setRightKey(8L);
         userTemplate.getMemberships().add(membershipTO);
-        task.setUserTemplate(userTemplate);
+        task.getTemplates().put(AnyTypeKind.USER.name(), userTemplate);
 
         GroupTO groupTemplate = new GroupTO();
         groupTemplate.getResources().add(RESOURCE_NAME_LDAP);
-        task.setGroupTemplate(groupTemplate);
+        task.getTemplates().put(AnyTypeKind.GROUP.name(), groupTemplate);
 
         Response response = taskService.create(task);
         SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
@@ -124,8 +125,8 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertNotNull(task);
         assertEquals(actual.getKey(), task.getKey());
         assertEquals(actual.getJobClassName(), task.getJobClassName());
-        assertEquals(userTemplate, task.getUserTemplate());
-        assertEquals(groupTemplate, task.getGroupTemplate());
+        assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
+        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
     }
 
     @Test
@@ -185,7 +186,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
             assertEquals(1, userTO.getMemberships().size());
-            assertTrue(userTO.getMemberships().get(0).getPlainAttrMap().containsKey("subscriptionDate"));
+            assertEquals(8, userTO.getMemberships().get(0).getRightKey());
 
             // Unmatching --> Assign (link) - SYNCOPE-658
             assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
@@ -378,7 +379,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
 
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7L);
+        membershipTO.setRightKey(7L);
 
         userTO.getMemberships().add(membershipTO);
 
@@ -396,7 +397,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             UserTO template = new UserTO();
 
             membershipTO = new MembershipTO();
-            membershipTO.setGroupKey(10L);
+            membershipTO.setRightKey(10L);
 
             template.getMemberships().add(membershipTO);
 
@@ -407,14 +408,14 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             SyncTaskTO task = taskService.read(9L);
             assertNotNull(task);
 
-            task.setUserTemplate(template);
+            task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
             taskService.update(task.getKey(), task);
             SyncTaskTO actual = taskService.read(task.getKey());
             assertNotNull(actual);
             assertEquals(task.getKey(), actual.getKey());
-            assertFalse(actual.getUserTemplate().getResources().isEmpty());
-            assertFalse(actual.getUserTemplate().getMemberships().isEmpty());
+            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
+            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getMemberships().isEmpty());
 
             TaskExecTO execution = execSyncTask(actual.getKey(), 50, false);
             final String status = execution.getStatus();
@@ -464,7 +465,15 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         // Add a custom correlation rule
         // -----------------------------
         SyncPolicyTO policyTO = policyService.read(9L);
-        policyTO.getSpecification().setUserJavaRule(TestSyncRule.class.getName());
+
+        SyncPolicySpecItem item = policyTO.getSpecification().getItem(AnyTypeKind.USER.name());
+        if (item == null) {
+            item = new SyncPolicySpecItem();
+            item.setAnyTypeKey(AnyTypeKind.USER.name());
+
+            policyTO.getSpecification().getItems().add(item);
+        }
+        item.setJavaRule(TestSyncRule.class.getName());
 
         policyService.update(policyTO.getKey(), policyTO);
         // -----------------------------
@@ -571,7 +580,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         AttrTO email = attrTO("email", "'s307@apache.org'");
         template.getPlainAttrs().add(email);
 
-        task.setUserTemplate(template);
+        task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
         taskService.update(task.getKey(), task);
         execSyncTask(task.getKey(), 50, false);
@@ -675,7 +684,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         // 4. Check that the LDAP resource has the old password
         ConnObjectTO connObject =
-                resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, user.getKey());
+                resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
         assertNotNull(getLdapRemoteObject(
                 connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
                 "security123",


[27/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
new file mode 100644
index 0000000..6d2eb1b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "anyObject")
+@XmlType
+public class AnyObjectTO extends AnyTO {
+
+    private static final long serialVersionUID = 8841697496476959639L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
new file mode 100644
index 0000000..bac9947
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType
+public abstract class AnyTO extends ConnObjectTO {
+
+    private static final long serialVersionUID = -754311920679872084L;
+
+    private long key;
+
+    private String type;
+
+    private String realm;
+
+    private String status;
+
+    private final Set<AttrTO> derAttrs = new LinkedHashSet<>();
+
+    private final Set<AttrTO> virAttrs = new LinkedHashSet<>();
+
+    private final Set<String> resources = new HashSet<>();
+
+    private final List<PropagationStatus> propagationStatusTOs = new ArrayList<>();
+
+    private final List<RelationshipTO> relationships = new ArrayList<>();
+
+    private final List<MembershipTO> memberships = new ArrayList<>();
+
+    private final List<Long> dynGroups = new ArrayList<>();
+
+    public long getKey() {
+        return key;
+    }
+
+    public void setKey(final long key) {
+        this.key = key;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(final String type) {
+        this.type = type;
+    }
+
+    public String getRealm() {
+        return realm;
+    }
+
+    public void setRealm(final String realm) {
+        this.realm = realm;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(final String status) {
+        this.status = status;
+    }
+
+    @XmlElementWrapper(name = "derAttrs")
+    @XmlElement(name = "attribute")
+    @JsonProperty("derAttrs")
+    public Set<AttrTO> getDerAttrs() {
+        return derAttrs;
+    }
+
+    @JsonIgnore
+    public Map<String, AttrTO> getDerAttrMap() {
+        Map<String, AttrTO> result = new HashMap<>(derAttrs.size());
+        for (AttrTO attributeTO : derAttrs) {
+            result.put(attributeTO.getSchema(), attributeTO);
+        }
+
+        return Collections.unmodifiableMap(result);
+    }
+
+    @XmlElementWrapper(name = "virAttrs")
+    @XmlElement(name = "attribute")
+    @JsonProperty("virAttrs")
+    public Set<AttrTO> getVirAttrs() {
+        return virAttrs;
+    }
+
+    @JsonIgnore
+    public Map<String, AttrTO> getVirAttrMap() {
+        Map<String, AttrTO> result = new HashMap<>(virAttrs.size());
+        for (AttrTO attributeTO : virAttrs) {
+            result.put(attributeTO.getSchema(), attributeTO);
+        }
+
+        return Collections.unmodifiableMap(result);
+    }
+
+    @XmlElementWrapper(name = "resources")
+    @XmlElement(name = "resource")
+    @JsonProperty("resources")
+    public Set<String> getResources() {
+        return resources;
+    }
+
+    @XmlElementWrapper(name = "propagationStatuses")
+    @XmlElement(name = "propagationStatus")
+    @JsonProperty("propagationStatuses")
+    public List<PropagationStatus> getPropagationStatusTOs() {
+        return propagationStatusTOs;
+    }
+
+    @XmlElementWrapper(name = "relationships")
+    @XmlElement(name = "relationship")
+    @JsonProperty("relationships")
+    public List<RelationshipTO> getRelationships() {
+        return relationships;
+    }
+
+    @XmlElementWrapper(name = "memberships")
+    @XmlElement(name = "membership")
+    @JsonProperty("memberships")
+    public List<MembershipTO> getMemberships() {
+        return memberships;
+    }
+
+    @JsonIgnore
+    public Map<Long, MembershipTO> getMembershipMap() {
+        Map<Long, MembershipTO> result;
+
+        if (getMemberships() == null) {
+            result = Collections.emptyMap();
+        } else {
+            result = new HashMap<>(getMemberships().size());
+            for (MembershipTO membership : getMemberships()) {
+                result.put(membership.getRightKey(), membership);
+            }
+            result = Collections.unmodifiableMap(result);
+        }
+
+        return result;
+    }
+
+    @XmlElementWrapper(name = "dynGroups")
+    @XmlElement(name = "role")
+    @JsonProperty("dynGroups")
+    public List<Long> getDynGroups() {
+        return dynGroups;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConfTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConfTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConfTO.java
index 4856a48..77e1af2 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConfTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConfTO.java
@@ -23,7 +23,7 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "conf")
 @XmlType
-public class ConfTO extends AbstractAttributableTO {
+public class ConfTO extends AnyTO {
 
     private static final long serialVersionUID = -3825039700228595590L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
index da0bd2b..873b15d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
@@ -19,19 +19,13 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "group")
 @XmlType
 @JsonIgnoreProperties({ "displayName" })
-public class GroupTO extends AbstractSubjectTO {
+public class GroupTO extends AnyTO {
 
     private static final long serialVersionUID = -7785920258290147542L;
 
@@ -41,19 +35,9 @@ public class GroupTO extends AbstractSubjectTO {
 
     private Long groupOwner;
 
-    private final List<String> gPlainAttrTemplates = new ArrayList<>();
-
-    private final List<String> gDerAttrTemplates = new ArrayList<>();
-
-    private final List<String> gVirAttrTemplates = new ArrayList<>();
-
-    private final List<String> mPlainAttrTemplates = new ArrayList<>();
+    private String aDynMembershipCond;
 
-    private final List<String> mDerAttrTemplates = new ArrayList<>();
-
-    private final List<String> mVirAttrTemplates = new ArrayList<>();
-
-    private String dynMembershipCond;
+    private String uDynMembershipCond;
 
     public String getName() {
         return name;
@@ -79,54 +63,20 @@ public class GroupTO extends AbstractSubjectTO {
         this.groupOwner = groupOwner;
     }
 
-    @XmlElementWrapper(name = "gPlainAttrTemplates")
-    @XmlElement(name = "gPlainAttrTemplate")
-    @JsonProperty("gPlainAttrTemplates")
-    public List<String> getGPlainAttrTemplates() {
-        return gPlainAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "gDerAttrTemplates")
-    @XmlElement(name = "gDerAttrTemplate")
-    @JsonProperty("gDerAttrTemplates")
-    public List<String> getGDerAttrTemplates() {
-        return gDerAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "gVirAttrTemplates")
-    @XmlElement(name = "gVirAttrTemplate")
-    @JsonProperty("gVirAttrTemplates")
-    public List<String> getGVirAttrTemplates() {
-        return gVirAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "mPlainAttrTemplates")
-    @XmlElement(name = "mPlainAttrTemplate")
-    @JsonProperty("mPlainAttrTemplates")
-    public List<String> getMPlainAttrTemplates() {
-        return mPlainAttrTemplates;
-    }
-
-    @XmlElementWrapper(name = "mDerAttrTemplates")
-    @XmlElement(name = "mDerAttrTemplate")
-    @JsonProperty("mDerAttrTemplates")
-    public List<String> getMDerAttrTemplates() {
-        return mDerAttrTemplates;
+    public String getADynMembershipCond() {
+        return aDynMembershipCond;
     }
 
-    @XmlElementWrapper(name = "mVirAttrTemplates")
-    @XmlElement(name = "mVirAttrTemplate")
-    @JsonProperty("mVirAttrTemplates")
-    public List<String> getMVirAttrTemplates() {
-        return mVirAttrTemplates;
+    public void setADynMembershipCond(final String aDynMembershipCond) {
+        this.aDynMembershipCond = aDynMembershipCond;
     }
 
-    public String getDynMembershipCond() {
-        return dynMembershipCond;
+    public String getUDynMembershipCond() {
+        return uDynMembershipCond;
     }
 
-    public void setDynMembershipCond(final String dynMembershipCond) {
-        this.dynMembershipCond = dynMembershipCond;
+    public void setUDynMembershipCond(final String uDynMembershipCond) {
+        this.uDynMembershipCond = uDynMembershipCond;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index 7d81cd8..cf5dc71 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -36,19 +36,19 @@ public class MappingTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 8447688036282611118L;
 
-    private String accountLink;
+    private String connObjectLink;
 
     private final List<MappingItemTO> items = new ArrayList<>();
 
-    public String getAccountLink() {
-        return accountLink;
+    public String getConnObjectLink() {
+        return connObjectLink;
     }
 
-    public void setAccountLink(final String accountLink) {
-        this.accountLink = accountLink;
+    public void setConnObjectLink(final String connObjectLink) {
+        this.connObjectLink = connObjectLink;
     }
 
-    public MappingItemTO getAccountIdItem() {
+    public MappingItemTO getConnObjectKeyItem() {
         return CollectionUtils.find(getItems(), new Predicate<MappingItemTO>() {
 
             @Override
@@ -58,48 +58,28 @@ public class MappingTO extends AbstractBaseBean {
         });
     }
 
-    protected boolean addAccountIdItem(final MappingItemTO accountIdItem) {
-        if (IntMappingType.UserVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.GroupVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.MembershipVirtualSchema == accountIdItem.getIntMappingType()
-                || IntMappingType.Password == accountIdItem.getIntMappingType()) {
+    protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
+        if (IntMappingType.UserVirtualSchema == connObjectItem.getIntMappingType()
+                || IntMappingType.GroupVirtualSchema == connObjectItem.getIntMappingType()
+                || IntMappingType.AnyVirtualSchema == connObjectItem.getIntMappingType()
+                || IntMappingType.Password == connObjectItem.getIntMappingType()) {
 
             throw new IllegalArgumentException("Virtual attributes cannot be set as accountId");
         }
-        if (IntMappingType.Password == accountIdItem.getIntMappingType()) {
+        if (IntMappingType.Password == connObjectItem.getIntMappingType()) {
             throw new IllegalArgumentException("Password attributes cannot be set as accountId");
         }
 
-        accountIdItem.setExtAttrName(accountIdItem.getExtAttrName());
-        accountIdItem.setAccountid(true);
+        connObjectItem.setExtAttrName(connObjectItem.getExtAttrName());
+        connObjectItem.setAccountid(true);
 
-        return this.addItem(accountIdItem);
+        return this.add(connObjectItem);
     }
 
-    public boolean setAccountIdItem(final MappingItemTO accountIdItem) {
-        return accountIdItem == null
-                ? removeItem(getAccountIdItem())
-                : addAccountIdItem(accountIdItem);
-    }
-
-    public MappingItemTO getPasswordItem() {
-        return CollectionUtils.find(getItems(), new Predicate<MappingItemTO>() {
-
-            @Override
-            public boolean evaluate(final MappingItemTO item) {
-                return item.isPassword();
-            }
-        });
-    }
-
-    public boolean setPasswordItem(final MappingItemTO passwordItem) {
-        if (passwordItem == null) {
-            return this.removeItem(getPasswordItem());
-        } else {
-            passwordItem.setExtAttrName(null);
-            passwordItem.setPassword(true);
-            return addItem(passwordItem);
-        }
+    public boolean setConnObjectKeyItem(final MappingItemTO connObjectKeyItem) {
+        return connObjectKeyItem == null
+                ? remove(getConnObjectKeyItem())
+                : addConnObjectKeyItem(connObjectKeyItem);
     }
 
     @XmlElementWrapper(name = "items")
@@ -109,11 +89,11 @@ public class MappingTO extends AbstractBaseBean {
         return items;
     }
 
-    public boolean addItem(final MappingItemTO item) {
+    public boolean add(final MappingItemTO item) {
         return item == null ? false : this.items.contains(item) || this.items.add(item);
     }
 
-    public boolean removeItem(final MappingItemTO item) {
+    public boolean remove(final MappingItemTO item) {
         return this.items.remove(item);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java
index 2d2c7fa..5c435e4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java
@@ -23,20 +23,15 @@ import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "membership")
 @XmlType
-public class MembershipTO extends AbstractAttributableTO {
+public class MembershipTO extends RelationshipTO {
 
     private static final long serialVersionUID = 5992828670273935861L;
 
-    private long groupKey;
-
     private String groupName;
 
-    public long getGroupKey() {
-        return groupKey;
-    }
-
-    public void setGroupKey(final long groupId) {
-        this.groupKey = groupId;
+    @Override
+    public String getRightType() {
+        return "group";
     }
 
     public String getGroupName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
index d56d2ea..662a465 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -39,9 +41,7 @@ public class NotificationTO extends AbstractBaseBean {
 
     private final List<String> events = new ArrayList<>();
 
-    private String userAbout;
-
-    private String groupAbout;
+    private final Map<String, String> abouts = new HashMap<>();
 
     private String recipients;
 
@@ -63,20 +63,8 @@ public class NotificationTO extends AbstractBaseBean {
 
     private boolean active;
 
-    public String getUserAbout() {
-        return userAbout;
-    }
-
-    public void setUserAbout(final String userAbout) {
-        this.userAbout = userAbout;
-    }
-
-    public String getGroupAbout() {
-        return groupAbout;
-    }
-
-    public void setGroupAbout(final String groupAbout) {
-        this.groupAbout = groupAbout;
+    public Map<String, String> getAbouts() {
+        return abouts;
     }
 
     @XmlElementWrapper(name = "events")

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
index 7c6ec08..0ebfb70 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
@@ -20,9 +20,9 @@ package org.apache.syncope.common.lib.to;
 
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.SubjectType;
 
 @XmlRootElement(name = "propagationTask")
 @XmlType
@@ -34,9 +34,9 @@ public class PropagationTaskTO extends AbstractTaskTO {
 
     private ResourceOperation propagationOperation;
 
-    private String accountId;
+    private String connObjectKey;
 
-    private String oldAccountId;
+    private String oldConnObjectKey;
 
     private String xmlAttributes;
 
@@ -44,24 +44,24 @@ public class PropagationTaskTO extends AbstractTaskTO {
 
     private String objectClassName;
 
-    private SubjectType subjectType;
+    private AnyTypeKind anyTypeKind;
 
-    private Long subjectId;
+    private Long anyKey;
 
-    public String getAccountId() {
-        return accountId;
+    public String getConnObjectKey() {
+        return connObjectKey;
     }
 
-    public void setAccountId(final String accountId) {
-        this.accountId = accountId;
+    public void setConnObjectKey(final String connObjectKey) {
+        this.connObjectKey = connObjectKey;
     }
 
-    public String getOldAccountId() {
-        return oldAccountId;
+    public String getOldConnObjectKey() {
+        return oldConnObjectKey;
     }
 
-    public void setOldAccountId(final String oldAccountId) {
-        this.oldAccountId = oldAccountId;
+    public void setOldConnObjectKey(final String oldConnObjectKey) {
+        this.oldConnObjectKey = oldConnObjectKey;
     }
 
     public PropagationMode getPropagationMode() {
@@ -85,7 +85,6 @@ public class PropagationTaskTO extends AbstractTaskTO {
     }
 
     public void setPropagationOperation(final ResourceOperation propagationOperation) {
-
         this.propagationOperation = propagationOperation;
     }
 
@@ -105,19 +104,19 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.objectClassName = objectClassName;
     }
 
-    public SubjectType getSubjectType() {
-        return subjectType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
-    public void setSubjectType(final SubjectType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
-    public Long getSubjectId() {
-        return subjectId;
+    public Long getAnyKey() {
+        return anyKey;
     }
 
-    public void setSubjectId(final Long subjectId) {
-        this.subjectId = subjectId;
+    public void setAnyKey(final Long anyKey) {
+        this.anyKey = anyKey;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
new file mode 100644
index 0000000..c4ff740
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisionTO.java
@@ -0,0 +1,77 @@
+/*
+ * 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 org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class ProvisionTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 8298910216218007927L;
+
+    private long key;
+
+    private String anyType;
+
+    private String objectClass;
+
+    private String syncToken;
+
+    private MappingTO mapping;
+
+    public long getKey() {
+        return key;
+    }
+
+    public void setKey(final long key) {
+        this.key = key;
+    }
+
+    public String getAnyType() {
+        return anyType;
+    }
+
+    public void setAnyType(final String anyType) {
+        this.anyType = anyType;
+    }
+
+    public String getObjectClass() {
+        return objectClass;
+    }
+
+    public void setObjectClass(final String objectClass) {
+        this.objectClass = objectClass;
+    }
+
+    public String getSyncToken() {
+        return syncToken;
+    }
+
+    public void setSyncToken(final String syncToken) {
+        this.syncToken = syncToken;
+    }
+
+    public MappingTO getMapping() {
+        return mapping;
+    }
+
+    public void setMapping(final MappingTO mapping) {
+        this.mapping = mapping;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
index 8ddf044..e1839af 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import java.util.HashMap;
+import java.util.Map;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
@@ -27,23 +29,10 @@ public class PushTaskTO extends AbstractProvisioningTaskTO {
 
     private static final long serialVersionUID = -2143537546915809018L;
 
-    private String userFilter;
+    private final Map<String, String> filters = new HashMap<>();
 
-    private String groupFilter;
-
-    public String getUserFilter() {
-        return userFilter;
-    }
-
-    public void setUserFilter(final String filter) {
-        this.userFilter = filter;
+    public Map<String, String> getFilters() {
+        return filters;
     }
 
-    public String getGroupFilter() {
-        return groupFilter;
-    }
-
-    public void setGroupFilter(final String filter) {
-        this.groupFilter = filter;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
new file mode 100644
index 0000000..2585b2b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
@@ -0,0 +1,81 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "relationship")
+@XmlType
+public class RelationshipTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 360672942026613929L;
+
+    private long key;
+
+    private String leftType;
+
+    private long leftKey;
+
+    private String rightType;
+
+    private long rightKey;
+
+    public long getKey() {
+        return key;
+    }
+
+    public void setKey(final long key) {
+        this.key = key;
+    }
+
+    public String getLeftType() {
+        return leftType;
+    }
+
+    public void setLeftType(final String leftType) {
+        this.leftType = leftType;
+    }
+
+    public long getLeftKey() {
+        return leftKey;
+    }
+
+    public void setLeftKey(final long leftKey) {
+        this.leftKey = leftKey;
+    }
+
+    public String getRightType() {
+        return rightType;
+    }
+
+    public void setRightType(final String rightType) {
+        this.rightType = rightType;
+    }
+
+    public long getRightKey() {
+        return rightKey;
+    }
+
+    public void setRightKey(final long rightKey) {
+        this.rightKey = rightKey;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
index 43f5ff0..fb97113 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ResourceTO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -27,6 +28,8 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.TraceLevel;
@@ -52,9 +55,7 @@ public class ResourceTO extends AbstractAnnotatedBean {
      */
     private String connectorDisplayName;
 
-    private MappingTO umapping;
-
-    private MappingTO gmapping;
+    private final List<ProvisionTO> provisions = new ArrayList<>();
 
     private boolean propagationPrimary;
 
@@ -132,22 +133,6 @@ public class ResourceTO extends AbstractAnnotatedBean {
         this.connectorDisplayName = connectorDisplayName;
     }
 
-    public MappingTO getUmapping() {
-        return umapping;
-    }
-
-    public void setUmapping(final MappingTO umapping) {
-        this.umapping = umapping;
-    }
-
-    public MappingTO getGmapping() {
-        return gmapping;
-    }
-
-    public void setGmapping(final MappingTO gmapping) {
-        this.gmapping = gmapping;
-    }
-
     public boolean isPropagationPrimary() {
         return propagationPrimary;
     }
@@ -228,6 +213,24 @@ public class ResourceTO extends AbstractAnnotatedBean {
         this.syncPolicy = syncPolicy;
     }
 
+    @JsonIgnore
+    public ProvisionTO getProvision(final String anyType) {
+        return CollectionUtils.find(provisions, new Predicate<ProvisionTO>() {
+
+            @Override
+            public boolean evaluate(final ProvisionTO provisionTO) {
+                return anyType != null && anyType.equals(provisionTO.getAnyType());
+            }
+        });
+    }
+
+    @XmlElementWrapper(name = "provisions")
+    @XmlElement(name = "provision")
+    @JsonProperty("provisions")
+    public List<ProvisionTO> getProvisions() {
+        return provisions;
+    }
+
     @XmlElementWrapper(name = "connConfProperties")
     @XmlElement(name = "property")
     @JsonProperty("connConfProperties")
@@ -243,22 +246,6 @@ public class ResourceTO extends AbstractAnnotatedBean {
         this.syncTraceLevel = syncTraceLevel;
     }
 
-    public String getUsyncToken() {
-        return usyncToken;
-    }
-
-    public void setUsyncToken(final String syncToken) {
-        this.usyncToken = syncToken;
-    }
-
-    public String getRsyncToken() {
-        return rsyncToken;
-    }
-
-    public void setRsyncToken(final String syncToken) {
-        this.rsyncToken = syncToken;
-    }
-
     @XmlElementWrapper(name = "propagationActionsClassNames")
     @XmlElement(name = "propagationActionsClassName")
     @JsonProperty("propagationActionsClassNames")

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
index e62ffe4..4974505 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncTaskTO.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import java.util.HashMap;
+import java.util.Map;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
@@ -29,9 +31,7 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO {
 
     private String destinationRealm;
 
-    private UserTO userTemplate;
-
-    private GroupTO groupTemplate;
+    private final Map<String, AnyTO> templates = new HashMap<>();
 
     private boolean fullReconciliation;
 
@@ -43,20 +43,8 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO {
         this.destinationRealm = destinationRealm;
     }
 
-    public UserTO getUserTemplate() {
-        return userTemplate;
-    }
-
-    public void setUserTemplate(final UserTO userTemplate) {
-        this.userTemplate = userTemplate;
-    }
-
-    public GroupTO getGroupTemplate() {
-        return groupTemplate;
-    }
-
-    public void setGroupTemplate(final GroupTO groupTemplate) {
-        this.groupTemplate = groupTemplate;
+    public Map<String, AnyTO> getTemplates() {
+        return templates;
     }
 
     public boolean isFullReconciliation() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
index 03dda04..243a79f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SyncopeTO.java
@@ -43,12 +43,16 @@ public class SyncopeTO extends AbstractBaseBean {
 
     private final List<String> connIdLocations = new ArrayList<>();
 
-    private String attributableTransformer;
+    private String anyTransformer;
+
+    private String anyObjectWorkflowAdapter;
 
     private String userWorkflowAdapter;
 
     private String groupWorkflowAdapter;
 
+    private String anyObjectProvisioningManager;
+
     private String userProvisioningManager;
 
     private String groupProvisioningManager;
@@ -96,8 +100,12 @@ public class SyncopeTO extends AbstractBaseBean {
         return connIdLocations;
     }
 
-    public String getAttributableTransformer() {
-        return attributableTransformer;
+    public String getAnyTransformer() {
+        return anyTransformer;
+    }
+
+    public String getAnyObjectWorkflowAdapter() {
+        return anyObjectWorkflowAdapter;
     }
 
     public String getUserWorkflowAdapter() {
@@ -108,6 +116,10 @@ public class SyncopeTO extends AbstractBaseBean {
         return groupWorkflowAdapter;
     }
 
+    public String getAnyObjectProvisioningManager() {
+        return anyObjectProvisioningManager;
+    }
+
     public String getUserProvisioningManager() {
         return userProvisioningManager;
     }
@@ -199,8 +211,12 @@ public class SyncopeTO extends AbstractBaseBean {
         this.pwdResetRequiringSecurityQuestions = pwdResetRequiringSecurityQuestions;
     }
 
-    public void setAttributableTransformer(final String attributableTransformer) {
-        this.attributableTransformer = attributableTransformer;
+    public void setAnyTransformer(final String anyTransformer) {
+        this.anyTransformer = anyTransformer;
+    }
+
+    public void setAnyObjectWorkflowAdapter(final String anyObjectWorkflowAdapter) {
+        this.anyObjectWorkflowAdapter = anyObjectWorkflowAdapter;
     }
 
     public void setUserWorkflowAdapter(final String userWorkflowAdapter) {
@@ -211,6 +227,10 @@ public class SyncopeTO extends AbstractBaseBean {
         this.groupWorkflowAdapter = groupWorkflowAdapter;
     }
 
+    public void setAnyObjectProvisioningManager(final String anyObjectProvisioningManager) {
+        this.anyObjectProvisioningManager = anyObjectProvisioningManager;
+    }
+
     public void setUserProvisioningManager(final String userProvisioningManager) {
         this.userProvisioningManager = userProvisioningManager;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index 2feeffe..5de7b01 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -18,15 +18,11 @@
  */
 package org.apache.syncope.common.lib.to;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -36,7 +32,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
 
 @XmlRootElement(name = "user")
 @XmlType
-public class UserTO extends AbstractSubjectTO {
+public class UserTO extends AnyTO {
 
     private static final long serialVersionUID = 7791304495192615740L;
 
@@ -46,12 +42,6 @@ public class UserTO extends AbstractSubjectTO {
 
     private final List<Long> dynRoles = new ArrayList<>();
 
-    private final List<MembershipTO> memberships = new ArrayList<>();
-
-    private final List<Long> dynGroups = new ArrayList<>();
-
-    private String status;
-
     private String token;
 
     private Date tokenExpireTime;
@@ -90,45 +80,6 @@ public class UserTO extends AbstractSubjectTO {
         return dynRoles;
     }
 
-    @XmlElementWrapper(name = "memberships")
-    @XmlElement(name = "membership")
-    @JsonProperty("memberships")
-    public List<MembershipTO> getMemberships() {
-        return memberships;
-    }
-
-    @JsonIgnore
-    public Map<Long, MembershipTO> getMembershipMap() {
-        Map<Long, MembershipTO> result;
-
-        if (getMemberships() == null) {
-            result = Collections.emptyMap();
-        } else {
-            result = new HashMap<>(getMemberships().size());
-            for (MembershipTO membership : getMemberships()) {
-                result.put(membership.getGroupKey(), membership);
-            }
-            result = Collections.unmodifiableMap(result);
-        }
-
-        return result;
-    }
-
-    @XmlElementWrapper(name = "dynGroups")
-    @XmlElement(name = "role")
-    @JsonProperty("dynGroups")
-    public List<Long> getDynGroups() {
-        return dynGroups;
-    }
-
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(final String status) {
-        this.status = status;
-    }
-
     public String getToken() {
         return token;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/AnyTypeKind.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AnyTypeKind.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AnyTypeKind.java
new file mode 100644
index 0000000..c7b4e47
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AnyTypeKind.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum AnyTypeKind {
+
+    USER,
+    GROUP,
+    ANY_OBJECT;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java
deleted file mode 100644
index fab34f0..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AttributableType.java
+++ /dev/null
@@ -1,31 +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.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum AttributableType {
-
-    USER,
-    GROUP,
-    MEMBERSHIP,
-    CONFIGURATION;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
index a149d6c..81caa77 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
@@ -80,6 +80,18 @@ public final class Entitlement {
 
     public static final String GROUP_DELETE = "GROUP_DELETE";
 
+    public static final String ANY_OBJECT_SEARCH = "ANY_OBJECT_SEARCH";
+
+    public static final String ANY_OBJECT_LIST = "ANY_OBJECT_LIST";
+
+    public static final String ANY_OBJECT_CREATE = "ANY_OBJECT_CREATE";
+
+    public static final String ANY_OBJECT_READ = "ANY_OBJECT_READ";
+
+    public static final String ANY_OBJECT_UPDATE = "ANY_OBJECT_UPDATE";
+
+    public static final String ANY_OBJECT_DELETE = "ANY_OBJECT_DELETE";
+
     public static final String RESOURCE_LIST = "RESOURCE_LIST";
 
     public static final String RESOURCE_CREATE = "RESOURCE_CREATE";

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
index c02913f..2192bd5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
@@ -27,20 +27,13 @@ public enum EntityViolationType {
     InvalidAccountPolicy("org.apache.syncope.core.persistence.validation.accountpolicy"),
     InvalidConnInstanceLocation("org.apache.syncope.core.persistence.validation.conninstance.location"),
     InvalidConnPoolConf("org.apache.syncope.core.persistence.validation.conninstance.poolConf"),
-    InvalidCPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.cPlainSchema"),
     InvalidMapping("org.apache.syncope.core.persistence.validation.mapping"),
-    InvalidMPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.mPlainSchema"),
-    InvalidMDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.mDerSchema"),
-    InvalidMVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.mVirSchema"),
     InvalidName("org.apache.syncope.core.persistence.validation.name"),
     InvalidNotification("org.apache.syncope.core.persistence.validation.notification"),
     InvalidPassword("org.apache.syncope.core.persistence.validation.user.password"),
     InvalidPasswordPolicy("org.apache.syncope.core.persistence.validation.passwordpolicy"),
     InvalidPolicy("org.apache.syncope.core.persistence.validation.policy"),
     InvalidPropagationTask("org.apache.syncope.core.persistence.validation.propagationtask"),
-    InvalidGPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.gPlainSchema"),
-    InvalidGDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.gDerSchema"),
-    InvalidGVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.gVirSchema"),
     InvalidRealm("org.apache.syncope.core.persistence.validation.realm"),
     InvalidReport("org.apache.syncope.core.persistence.validation.report"),
     InvalidResource("org.apache.syncope.core.persistence.validation.externalresource"),
@@ -51,9 +44,9 @@ public enum EntityViolationType {
     InvalidSchedTask("org.apache.syncope.core.persistence.validation.schedtask"),
     InvalidSyncTask("org.apache.syncope.core.persistence.validation.synctask"),
     InvalidSyncPolicy("org.apache.syncope.core.persistence.validation.syncpolicy"),
-    InvalidUPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.uPlainSchema"),
-    InvalidUDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.derSchema"),
-    InvalidUVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.uVirSchema"),
+    InvalidPlainSchema("org.apache.syncope.core.persistence.validation.attrvalue.plainSchema"),
+    InvalidDerSchema("org.apache.syncope.core.persistence.validation.attrvalue.derSchema"),
+    InvalidVirSchema("org.apache.syncope.core.persistence.validation.attrvalue.virSchema"),
     InvalidUsername("org.apache.syncope.core.persistence.validation.user.username"),
     InvalidValueList("org.apache.syncope.core.persistence.validation.attr.valueList"),
     MoreThanOneNonNull("org.apache.syncope.core.persistence.validation.attrvalue.moreThanOneNonNull");

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
index c329d72..1b50f43 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
@@ -35,71 +35,71 @@ public enum IntMappingType {
     // -------------------------
     // User attribute types (the same in UserMappingType)
     // -------------------------
-    UserPlainSchema(AttributableType.USER),
-    UserDerivedSchema(AttributableType.USER),
-    UserVirtualSchema(AttributableType.USER),
-    UserId(AttributableType.USER),
-    Username(AttributableType.USER),
-    Password(AttributableType.USER),
+    UserPlainSchema(AnyTypeKind.USER),
+    UserDerivedSchema(AnyTypeKind.USER),
+    UserVirtualSchema(AnyTypeKind.USER),
+    UserId(AnyTypeKind.USER),
+    Username(AnyTypeKind.USER),
+    Password(AnyTypeKind.USER),
     // -------------------------
     // Group attribute types (the same in GroupMappingType)
     // -------------------------
-    GroupPlainSchema(AttributableType.GROUP),
-    GroupDerivedSchema(AttributableType.GROUP),
-    GroupVirtualSchema(AttributableType.GROUP),
-    GroupId(AttributableType.GROUP),
-    GroupName(AttributableType.GROUP),
-    GroupOwnerSchema(AttributableType.GROUP),
+    GroupPlainSchema(AnyTypeKind.GROUP),
+    GroupDerivedSchema(AnyTypeKind.GROUP),
+    GroupVirtualSchema(AnyTypeKind.GROUP),
+    GroupId(AnyTypeKind.GROUP),
+    GroupName(AnyTypeKind.GROUP),
+    GroupOwnerSchema(AnyTypeKind.GROUP),
     // -------------------------
-    // Membership attribute types (the same in MembershipMappingType)
+    // Any attribute types (the same in AnyMappingType)
     // -------------------------
-    MembershipPlainSchema(AttributableType.MEMBERSHIP),
-    MembershipDerivedSchema(AttributableType.MEMBERSHIP),
-    MembershipVirtualSchema(AttributableType.MEMBERSHIP),
-    MembershipId(AttributableType.MEMBERSHIP);
+    AnyPlainSchema(AnyTypeKind.ANY_OBJECT),
+    AnyDerivedSchema(AnyTypeKind.ANY_OBJECT),
+    AnyVirtualSchema(AnyTypeKind.ANY_OBJECT),
+    AnyId(AnyTypeKind.ANY_OBJECT);
 
-    private final AttributableType attributableType;
+    private final AnyTypeKind anyTypeKind;
 
-    private IntMappingType(final AttributableType attributableType) {
-        this.attributableType = attributableType;
+    private IntMappingType(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
-    public AttributableType getAttributableType() {
-        return attributableType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
     /**
-     * Get attribute types for a certain attributable type.
+     * Get attribute types for a certain any object type.
      *
-     * @param attributableType attributable type
+     * @param anyTypeKind any object type
      * @param toBeFiltered types to be filtered from the result.
      * @return set of attribute types.
      */
     public static Set<IntMappingType> getAttributeTypes(
-            final AttributableType attributableType, final Collection<IntMappingType> toBeFiltered) {
+            final AnyTypeKind anyTypeKind, final Collection<IntMappingType> toBeFiltered) {
 
-        final Set<IntMappingType> res = getAttributeTypes(attributableType);
+        final Set<IntMappingType> res = getAttributeTypes(anyTypeKind);
         res.removeAll(toBeFiltered);
 
         return res;
     }
 
     /**
-     * Get attribute types for a certain attributable type.
+     * Get attribute types for a certain any object type.
      *
-     * @param attributableType attributable type
+     * @param anyTypeKind any object type
      * @return set of attribute types.
      */
-    public static Set<IntMappingType> getAttributeTypes(final AttributableType attributableType) {
+    public static Set<IntMappingType> getAttributeTypes(final AnyTypeKind anyTypeKind) {
         EnumSet<?> enumset;
 
-        switch (attributableType) {
+        switch (anyTypeKind) {
             case GROUP:
                 enumset = EnumSet.allOf(GroupMappingType.class);
                 break;
 
-            case MEMBERSHIP:
-                enumset = EnumSet.allOf(MembershipMappingType.class);
+            case ANY_OBJECT:
+                enumset = EnumSet.allOf(AnyMappingType.class);
                 break;
 
             case USER:
@@ -119,18 +119,18 @@ public enum IntMappingType {
     public static Set<IntMappingType> getEmbedded() {
         return EnumSet.of(IntMappingType.UserId, IntMappingType.Username, IntMappingType.Password,
                 IntMappingType.GroupId, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema,
-                IntMappingType.MembershipId);
+                IntMappingType.AnyId);
     }
 
     /**
-     * Check if attribute type belongs to the specified attributable type set.
+     * Check if attribute type belongs to the specified any object type set.
      *
-     * @param attributableType attributable type.
+     * @param anyTypeKind any object type.
      * @param type attribute type.
-     * @return true if attribute type belongs to the specified attributable type set.
+     * @return true if attribute type belongs to the specified any object type set.
      */
-    public static boolean contains(final AttributableType attributableType, final String type) {
-        switch (attributableType) {
+    public static boolean contains(final AnyTypeKind anyTypeKind, final String type) {
+        switch (anyTypeKind) {
             case GROUP:
                 for (GroupMappingType c : GroupMappingType.values()) {
                     if (c.name().equals(type)) {
@@ -139,8 +139,8 @@ public enum IntMappingType {
                 }
                 break;
 
-            case MEMBERSHIP:
-                for (MembershipMappingType c : MembershipMappingType.values()) {
+            case ANY_OBJECT:
+                for (AnyMappingType c : AnyMappingType.values()) {
                     if (c.name().equals(type)) {
                         return true;
                     }
@@ -188,14 +188,14 @@ public enum IntMappingType {
     }
 
     /**
-     * Membership attribute types.
+     * Any attribute types.
      */
-    private enum MembershipMappingType {
+    private enum AnyMappingType {
 
-        MembershipPlainSchema,
-        MembershipDerivedSchema,
-        MembershipVirtualSchema,
-        MembershipId;
+        AnyPlainSchema,
+        AnyDerivedSchema,
+        AnyVirtualSchema,
+        AnyId;
 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java
deleted file mode 100644
index 538f19a..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SubjectType.java
+++ /dev/null
@@ -1,34 +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.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum SubjectType {
-
-    USER,
-    GROUP;
-
-    public AttributableType asAttributableType() {
-        return this == USER
-                ? AttributableType.USER
-                : AttributableType.GROUP;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
index a904209..34f95dd 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
@@ -24,31 +24,15 @@ import java.util.List;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.annotation.ClassList;
-import org.apache.syncope.common.lib.annotation.SchemaList;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 
 @XmlType
 public class SyncPolicySpec implements PolicySpec {
 
     private static final long serialVersionUID = -3144027171719498127L;
 
-    /**
-     * User attributes and fields for matching during synchronization.
-     */
-    @SchemaList(extended = true)
-    private final List<String> uAltSearchSchemas = new ArrayList<>();
-
-    @ClassList
-    private String userJavaRule;
-
-    /**
-     * Group attributes and fields for matching during synchronization.
-     */
-    @SchemaList(extended = true)
-    private final List<String> gAltSearchSchemas = new ArrayList<>();
-
-    @ClassList
-    private String groupJavaRule;
+    private final List<SyncPolicySpecItem> items = new ArrayList<>();
 
     /**
      * Conflict resolution action.
@@ -65,33 +49,20 @@ public class SyncPolicySpec implements PolicySpec {
         this.conflictResolutionAction = conflictResolutionAction;
     }
 
-    @XmlElementWrapper(name = "userAltSearchSchemas")
-    @XmlElement(name = "userAltSearchSchema")
-    @JsonProperty("userAltSearchSchemas")
-    public List<String> getuAltSearchSchemas() {
-        return uAltSearchSchemas;
-    }
-
-    @XmlElementWrapper(name = "groupAltSearchSchemas")
-    @XmlElement(name = "groupAltSearchSchema")
-    @JsonProperty("groupAltSearchSchemas")
-    public List<String> getrAltSearchSchemas() {
-        return gAltSearchSchemas;
-    }
-
-    public String getGroupJavaRule() {
-        return groupJavaRule;
-    }
-
-    public void setGroupJavaRule(final String groupJavaRule) {
-        this.groupJavaRule = groupJavaRule;
-    }
+    public SyncPolicySpecItem getItem(final String anyTypeKey) {
+        return CollectionUtils.find(items, new Predicate<SyncPolicySpecItem>() {
 
-    public String getUserJavaRule() {
-        return userJavaRule;
+            @Override
+            public boolean evaluate(final SyncPolicySpecItem item) {
+                return anyTypeKey != null && anyTypeKey.equals(item.getAnyTypeKey());
+            }
+        });
     }
 
-    public void setUserJavaRule(final String userJavaRule) {
-        this.userJavaRule = userJavaRule;
+    @XmlElementWrapper(name = "items")
+    @XmlElement(name = "item")
+    @JsonProperty("items")
+    public List<SyncPolicySpecItem> getItems() {
+        return items;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
new file mode 100644
index 0000000..4acb61b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
@@ -0,0 +1,67 @@
+/*
+ * 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.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.annotation.ClassList;
+import org.apache.syncope.common.lib.annotation.SchemaList;
+
+@XmlType
+public class SyncPolicySpecItem extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 692466729711976485L;
+
+    private String anyTypeKey;
+
+    @SchemaList(extended = true)
+    private final List<String> altSearchSchemas = new ArrayList<>();
+
+    @ClassList
+    private String javaRule;
+
+    public String getAnyTypeKey() {
+        return anyTypeKey;
+    }
+
+    public void setAnyTypeKey(final String anyTypeKey) {
+        this.anyTypeKey = anyTypeKey;
+    }
+
+    public String getJavaRule() {
+        return javaRule;
+    }
+
+    public void setJavaRule(final String javaRule) {
+        this.javaRule = javaRule;
+    }
+
+    @XmlElementWrapper(name = "altSearchSchemas")
+    @XmlElement(name = "altSearchSchema")
+    @JsonProperty("altSearchSchemas")
+    public List<String> getAltSearchSchemas() {
+        return altSearchSchemas;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/AnyKey.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/AnyKey.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/AnyKey.java
new file mode 100644
index 0000000..6db8870
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/AnyKey.java
@@ -0,0 +1,25 @@
+/*
+ * 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.wrap;
+
+public class AnyKey extends AbstractWrappable<Long> {
+
+    private static final long serialVersionUID = -8664228651057889297L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SubjectKey.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SubjectKey.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SubjectKey.java
deleted file mode 100644
index 930cf35..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/SubjectKey.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.common.lib.wrap;
-
-public class SubjectKey extends AbstractWrappable<Long> {
-
-    private static final long serialVersionUID = -8664228651057889297L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyListQuery.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyListQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyListQuery.java
new file mode 100644
index 0000000..e4fdf04
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyListQuery.java
@@ -0,0 +1,41 @@
+/*
+ * 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.rest.api.beans;
+
+import java.util.List;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.MatrixParam;
+import org.apache.syncope.common.lib.SyncopeConstants;
+
+public class AnyListQuery extends ListQuery {
+
+    private static final long serialVersionUID = -5197167078435619636L;
+
+    private List<String> realms;
+
+    public List<String> getRealms() {
+        return realms;
+    }
+
+    @DefaultValue(SyncopeConstants.ROOT_REALM)
+    @MatrixParam("realm")
+    public void setRealms(final List<String> realms) {
+        this.realms = realms;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnySearchQuery.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnySearchQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnySearchQuery.java
new file mode 100644
index 0000000..3e0a516
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnySearchQuery.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rest.api.beans;
+
+import javax.ws.rs.QueryParam;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
+
+public class AnySearchQuery extends AnyListQuery {
+
+    private static final long serialVersionUID = -6736562952418964707L;
+
+    private String fiql;
+
+    public String getFiql() {
+        return fiql;
+    }
+
+    @QueryParam(JAXRSService.PARAM_FIQL)
+    public void setFiql(final String fiql) {
+        this.fiql = fiql;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectListQuery.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectListQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectListQuery.java
deleted file mode 100644
index 47ff005..0000000
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectListQuery.java
+++ /dev/null
@@ -1,41 +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.rest.api.beans;
-
-import java.util.List;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.MatrixParam;
-import org.apache.syncope.common.lib.SyncopeConstants;
-
-public class SubjectListQuery extends ListQuery {
-
-    private static final long serialVersionUID = -5197167078435619636L;
-
-    private List<String> realms;
-
-    public List<String> getRealms() {
-        return realms;
-    }
-
-    @DefaultValue(SyncopeConstants.ROOT_REALM)
-    @MatrixParam("realm")
-    public void setRealms(final List<String> realms) {
-        this.realms = realms;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectSearchQuery.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectSearchQuery.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectSearchQuery.java
deleted file mode 100644
index d7f7344..0000000
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/SubjectSearchQuery.java
+++ /dev/null
@@ -1,39 +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.rest.api.beans;
-
-import javax.ws.rs.QueryParam;
-import org.apache.syncope.common.rest.api.service.JAXRSService;
-
-public class SubjectSearchQuery extends SubjectListQuery {
-
-    private static final long serialVersionUID = -6736562952418964707L;
-
-    private String fiql;
-
-    public String getFiql() {
-        return fiql;
-    }
-
-    @QueryParam(JAXRSService.PARAM_FIQL)
-    public void setFiql(final String fiql) {
-        this.fiql = fiql;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
index b612a6e..635be02 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
@@ -41,8 +41,8 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for groups.
@@ -85,7 +85,7 @@ public interface GroupService extends JAXRSService {
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> list(@BeanParam SubjectListQuery listQuery);
+    PagedResult<GroupTO> list(@BeanParam AnyListQuery listQuery);
 
     /**
      * Returns a paged list of groups matching the given query.
@@ -96,7 +96,7 @@ public interface GroupService extends JAXRSService {
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> search(@BeanParam SubjectSearchQuery searchQuery);
+    PagedResult<GroupTO> search(@BeanParam AnySearchQuery searchQuery);
 
     /**
      * Creates a new group.

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
index 06b6b32..48ba21a 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
@@ -38,8 +38,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.syncope.common.lib.wrap.AnyKey;
 
 /**
  * REST operations for external resources.
@@ -51,15 +50,15 @@ public interface ResourceService extends JAXRSService {
      * Returns connector object from the external resource, for the given type and key.
      *
      * @param resourceKey Name of resource to read connector object from
-     * @param type user /group
-     * @param key user key / group key
+     * @param anyTypeKey any object type
+     * @param key any object key
      * @return connector object from the external resource, for the given type and key
      */
     @GET
-    @Path("{resourceKey}/{type}/{key}")
+    @Path("{resourceKey}/{anyTypeKey}/{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ConnObjectTO getConnectorObject(@NotNull @PathParam("resourceKey") String resourceKey,
-            @NotNull @PathParam("type") SubjectType type, @NotNull @PathParam("key") Long key);
+    ConnObjectTO readConnObject(@NotNull @PathParam("resourceKey") String resourceKey,
+            @NotNull @PathParam("anyTypeKey") String anyTypeKey, @NotNull @PathParam("key") Long key);
 
     /**
      * Returns the resource with matching name.
@@ -117,7 +116,7 @@ public interface ResourceService extends JAXRSService {
     void delete(@NotNull @PathParam("resourceKey") String resourceKey);
 
     /**
-     * Checks wether the connection to resource could be established.
+     * Checks whether the connection to resource could be established.
      *
      * @param resourceTO resource to be checked
      * @return true if connection to resource could be established
@@ -128,12 +127,12 @@ public interface ResourceService extends JAXRSService {
     boolean check(@NotNull ResourceTO resourceTO);
 
     /**
-     * De-associate users or groups (depending on the provided subject type) from the given resource.
+     * De-associate any objects from the given resource.
      *
      * @param resourceKey name of resource
-     * @param subjectType subject type (user or group)
+     * @param anyTypeKey any object kind
      * @param type resource de-association action type
-     * @param subjectKeys users or groups against which the bulk action will be performed
+     * @param keys any object keys against which the bulk action will be performed
      * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
      */
     @Descriptions({
@@ -141,12 +140,12 @@ public interface ResourceService extends JAXRSService {
                 value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
     })
     @POST
-    @Path("{resourceKey}/bulkDeassociation/{subjType}/{type}")
+    @Path("{resourceKey}/bulkDeassociation/{anyTypeKey}/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     BulkActionResult bulkDeassociation(@NotNull @PathParam("resourceKey") String resourceKey,
-            @NotNull @PathParam("subjType") SubjectType subjectType,
-            @NotNull @PathParam("type") ResourceDeassociationActionType type, @NotNull List<SubjectKey> subjectKeys);
+            @NotNull @PathParam("anyTypeKey") String anyTypeKey,
+            @NotNull @PathParam("type") ResourceDeassociationActionType type, @NotNull List<AnyKey> keys);
 
     /**
      * Executes the provided bulk action.

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java
index d3f850b..4ffb3f6 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java
@@ -34,7 +34,6 @@ import org.apache.cxf.jaxrs.model.wadl.Description;
 import org.apache.cxf.jaxrs.model.wadl.Descriptions;
 import org.apache.cxf.jaxrs.model.wadl.DocTarget;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.SchemaType;
 
 /**
@@ -47,36 +46,32 @@ public interface SchemaService extends JAXRSService {
      * Returns schema matching the given kind, type and name.
      *
      * @param <T> actual SchemaTO
-     * @param attrType kind for schemas to be read
-     * @param schemaType type for schemas to be read
+     * @param type type for schemas to be read
      * @param schemaKey name of schema to be read
      * @return schema matching the given kind, type and name
      */
     @GET
     @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> T read(@NotNull @PathParam("kind") AttributableType attrType,
-            @NotNull @PathParam("type") SchemaType schemaType, @NotNull @PathParam("key") String schemaKey);
+    <T extends AbstractSchemaTO> T read(
+            @NotNull @PathParam("type") SchemaType type, @NotNull @PathParam("key") String schemaKey);
 
     /**
      * Returns a list of schemas with matching kind and type.
      *
      * @param <T> actual SchemaTO
-     * @param attrType kind for schemas to be listed
-     * @param schemaType type for schemas to be listed
+     * @param type type for schemas to be listed
      * @return list of schemas with matching kind and type
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> List<T> list(
-            @NotNull @PathParam("kind") AttributableType attrType, @NotNull @PathParam("type") SchemaType schemaType);
+    <T extends AbstractSchemaTO> List<T> list(@NotNull @PathParam("type") SchemaType type);
 
     /**
      * Creates a new schema.
      *
      * @param <T> actual SchemaTO
-     * @param attrType kind for schema to be created
-     * @param schemaType type for schema to be created
+     * @param type type for schema to be created
      * @param schemaTO schema to be created
      * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created schema
      */
@@ -85,35 +80,33 @@ public interface SchemaService extends JAXRSService {
     })
     @POST
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> Response create(@NotNull @PathParam("kind") AttributableType attrType,
-            @NotNull @PathParam("type") SchemaType schemaType, @NotNull T schemaTO);
+    <T extends AbstractSchemaTO> Response create(
+            @NotNull @PathParam("type") SchemaType type, @NotNull T schemaTO);
 
     /**
      * Updates the schema matching the given kind, type and name.
      *
      * @param <T> actual SchemaTO
-     * @param attrType kind for schemas to be updated
-     * @param schemaType type for schemas to be updated
+     * @param type type for schemas to be updated
      * @param schemaKey name of schema to be updated
      * @param schemaTO updated schema to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> void update(@NotNull @PathParam("kind") AttributableType attrType,
-            @NotNull @PathParam("type") SchemaType schemaType,
+    <T extends AbstractSchemaTO> void update(
+            @NotNull @PathParam("type") SchemaType type,
             @NotNull @PathParam("key") String schemaKey, @NotNull T schemaTO);
 
     /**
      * Deletes the schema matching the given kind, type and name.
      *
-     * @param attrType kind for schema to be deleted
-     * @param schemaType type for schema to be deleted
+     * @param type type for schema to be deleted
      * @param schemaKey name of schema to be deleted
      */
     @DELETE
     @Path("{key}")
-    void delete(@NotNull @PathParam("kind") AttributableType attrType,
-            @NotNull @PathParam("type") SchemaType schemaType,
+    void delete(
+            @NotNull @PathParam("type") SchemaType type,
             @NotNull @PathParam("key") String schemaKey);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index 8c13935..9e280a5 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -46,8 +46,8 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
-import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
-import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for users.
@@ -102,7 +102,7 @@ public interface UserService extends JAXRSService {
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> list(@BeanParam SubjectListQuery listQuery);
+    PagedResult<UserTO> list(@BeanParam AnyListQuery listQuery);
 
     /**
      * Returns a paged list of users matching the given query.
@@ -113,7 +113,7 @@ public interface UserService extends JAXRSService {
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@BeanParam SubjectSearchQuery searchQuery);
+    PagedResult<UserTO> search(@BeanParam AnySearchQuery searchQuery);
 
     /**
      * Creates a new user.


[15/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttrTemplate.java
deleted file mode 100644
index 427d91b..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerAttrTemplate.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity.group;
-
-import javax.persistence.Entity;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttrTemplate;
-
-@Entity
-@Table(name = JPAGDerAttrTemplate.TABLE)
-public class JPAGDerAttrTemplate extends AbstractDerAttrTemplate<GDerSchema> implements GDerAttrTemplate {
-
-    private static final long serialVersionUID = 624868884107016649L;
-
-    public static final String TABLE = "GDerAttrTemplate";
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAGDerSchema schema;
-
-    @Override
-    public GDerSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final GDerSchema schema) {
-        checkType(schema, JPAGDerSchema.class);
-        this.schema = (JPAGDerSchema) schema;
-    }
-
-    @Override
-    public Group getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group owner) {
-        checkType(owner, JPAGroup.class);
-        this.owner = (JPAGroup) owner;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerSchema.java
deleted file mode 100644
index b0a41ac..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGDerSchema.java
+++ /dev/null
@@ -1,34 +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.group;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-
-@Entity
-@Table(name = JPAGDerSchema.TABLE)
-public class JPAGDerSchema extends AbstractDerSchema implements GDerSchema {
-
-    private static final long serialVersionUID = -6868889736207576372L;
-
-    public static final String TABLE = "GDerSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMapping.java
deleted file mode 100644
index dd2679d..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMapping.java
+++ /dev/null
@@ -1,103 +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.group;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.group.GMapping;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMapping;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-
-@Entity
-@Table(name = JPAGMapping.TABLE)
-public class JPAGMapping extends AbstractMapping<GMappingItem> implements GMapping {
-
-    public static final String TABLE = "GMapping";
-
-    private static final long serialVersionUID = 4578756002867863392L;
-
-    @Id
-    private Long id;
-
-    /**
-     * Resource owning this mapping.
-     */
-    @OneToOne
-    private JPAExternalResource resource;
-
-    /**
-     * Attribute mappings.
-     */
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
-    private List<JPAGMappingItem> items;
-
-    public JPAGMapping() {
-        super();
-
-        items = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public ExternalResource getResource() {
-        return resource;
-    }
-
-    @Override
-    public void setResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        this.resource = (JPAExternalResource) resource;
-    }
-
-    @Override
-    public void setAccountIdItem(final GMappingItem item) {
-        checkType(item, JPAGMappingItem.class);
-        this.addAccountIdItem((JPAGMappingItem) item);
-    }
-
-    @Override
-    public List<? extends GMappingItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean addItem(final GMappingItem item) {
-        checkType(item, JPAGMappingItem.class);
-        return items.contains((JPAGMappingItem) item) || items.add((JPAGMappingItem) item);
-    }
-
-    @Override
-    public boolean removeItem(final GMappingItem item) {
-        checkType(item, JPAGMappingItem.class);
-        return items.remove((JPAGMappingItem) item);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMappingItem.java
deleted file mode 100644
index 2e3dd8e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGMappingItem.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.jpa.entity.group;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
-
-@Entity
-@Table(name = JPAGMappingItem.TABLE)
-public class JPAGMappingItem extends AbstractMappingItem implements GMappingItem {
-
-    public static final String TABLE = "GMappingItem";
-
-    private static final long serialVersionUID = -2670787666933476166L;
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAGMapping mapping;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Mapping<GMappingItem> getMapping() {
-        return mapping;
-    }
-
-    @Override
-    public void setMapping(final Mapping<?> mapping) {
-        checkType(mapping, JPAGMapping.class);
-        this.mapping = (JPAGMapping) mapping;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
index e4f8f06..daafd08 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.persistence.jpa.entity.group;
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.CascadeType;
-import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
@@ -30,21 +29,17 @@ import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.Valid;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 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.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
 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.GPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
 
 @Entity
 @Table(name = JPAGPlainAttr.TABLE)
-public class JPAGPlainAttr extends AbstractPlainAttr implements GPlainAttr {
+public class JPAGPlainAttr extends AbstractPlainAttr<Group> implements GPlainAttr {
 
     private static final long serialVersionUID = 2848159565890995780L;
 
@@ -56,23 +51,14 @@ public class JPAGPlainAttr extends AbstractPlainAttr implements GPlainAttr {
     @ManyToOne(fetch = FetchType.EAGER)
     private JPAGroup owner;
 
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAGPlainAttrTemplate template;
-
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
-    private List<JPAGPlainAttrValue> values;
+    private List<JPAGPlainAttrValue> values = new ArrayList<>();
 
     @OneToOne(cascade = CascadeType.ALL, mappedBy = "attribute")
     @Valid
     private JPAGPlainAttrUniqueValue uniqueValue;
 
-    public JPAGPlainAttr() {
-        super();
-        values = new ArrayList<>();
-    }
-
     @Override
     public Long getKey() {
         return id;
@@ -84,40 +70,19 @@ public class JPAGPlainAttr extends AbstractPlainAttr implements GPlainAttr {
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final Group owner) {
         checkType(owner, JPAGroup.class);
         this.owner = (JPAGroup) owner;
     }
 
     @Override
-    public GPlainAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final GPlainAttrTemplate template) {
-        checkType(template, JPAGPlainAttrTemplate.class);
-        this.template = (JPAGPlainAttrTemplate) template;
-    }
-
-    @Override
-    public GPlainSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        LOG.warn("This is group attribute, set template to select schema");
-    }
-
-    @Override
-    protected boolean addValue(final PlainAttrValue attrValue) {
+    protected boolean addForMultiValue(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAGPlainAttrValue.class);
         return values.add((JPAGPlainAttrValue) attrValue);
     }
 
     @Override
-    public boolean removeValue(final PlainAttrValue attrValue) {
+    public boolean remove(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAGPlainAttrValue.class);
         return values.remove((JPAGPlainAttrValue) attrValue);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrTemplate.java
deleted file mode 100644
index 2af988e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrTemplate.java
+++ /dev/null
@@ -1,75 +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.group;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrTemplate;
-
-@Entity
-@Table(name = JPAGPlainAttrTemplate.TABLE)
-public class JPAGPlainAttrTemplate extends AbstractPlainAttrTemplate<GPlainSchema> implements GPlainAttrTemplate {
-
-    private static final long serialVersionUID = 6943917051517266268L;
-
-    public static final String TABLE = "GPlainAttrTemplate";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAGPlainSchema schema;
-
-    @Override
-    public GPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final GPlainSchema schema) {
-        checkType(schema, JPAGPlainSchema.class);
-        this.schema = (JPAGPlainSchema) schema;
-    }
-
-    @Override
-    public Group getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group owner) {
-        checkType(owner, JPAGroup.class);
-        this.owner = (JPAGroup) owner;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java
index f361c03..3efae7c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java
@@ -28,8 +28,8 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 
 @Entity
 @Table(name = JPAGPlainAttrUniqueValue.TABLE)
@@ -47,7 +47,7 @@ public class JPAGPlainAttrUniqueValue extends AbstractPlainAttrValue implements
 
     @ManyToOne(optional = false)
     @JoinColumn(name = "schema_name")
-    private JPAGPlainSchema schema;
+    private JPAPlainSchema schema;
 
     @Override
     public Long getKey() {
@@ -66,13 +66,13 @@ public class JPAGPlainAttrUniqueValue extends AbstractPlainAttrValue implements
     }
 
     @Override
-    public GPlainSchema getSchema() {
+    public PlainSchema getSchema() {
         return schema;
     }
 
     @Override
     public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPAGPlainSchema.class);
-        this.schema = (JPAGPlainSchema) schema;
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainSchema.java
deleted file mode 100644
index 684be57..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainSchema.java
+++ /dev/null
@@ -1,36 +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.group;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
-
-@Entity
-@Table(name = JPAGPlainSchema.TABLE)
-@Cacheable
-public class JPAGPlainSchema extends AbstractPlainSchema implements GPlainSchema {
-
-    private static final long serialVersionUID = -7417234690221851342L;
-
-    public static final String TABLE = "GPlainSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttr.java
index 95d9a37..302e056 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttr.java
@@ -18,23 +18,16 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.group;
 
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
 
 @Entity
 @Table(name = JPAGVirAttr.TABLE)
-public class JPAGVirAttr extends AbstractVirAttr implements GVirAttr {
+public class JPAGVirAttr extends AbstractVirAttr<Group> implements GVirAttr {
 
     private static final long serialVersionUID = -1747430556914428649L;
 
@@ -43,40 +36,15 @@ public class JPAGVirAttr extends AbstractVirAttr implements GVirAttr {
     @ManyToOne
     private JPAGroup owner;
 
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAGVirAttrTemplate template;
-
     @Override
     public Group getOwner() {
         return owner;
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final Group owner) {
         checkType(owner, JPAGroup.class);
         this.owner = (JPAGroup) owner;
     }
 
-    @Override
-    public GVirAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final GVirAttrTemplate template) {
-        checkType(template, JPAGVirAttrTemplate.class);
-        this.template = (JPAGVirAttrTemplate) template;
-    }
-
-    @Override
-    public GVirSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final VirSchema schema) {
-        LOG.warn("This is group attribute, set template to select schema");
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttrTemplate.java
deleted file mode 100644
index 72f9fd3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirAttrTemplate.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity.group;
-
-import javax.persistence.Entity;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttrTemplate;
-
-@Entity
-@Table(name = JPAGVirAttrTemplate.TABLE)
-public class JPAGVirAttrTemplate extends AbstractVirAttrTemplate<GVirSchema> implements GVirAttrTemplate {
-
-    private static final long serialVersionUID = 4896495904794493479L;
-
-    public static final String TABLE = "GVirAttrTemplate";
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAGVirSchema schema;
-
-    @Override
-    public GVirSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final GVirSchema schema) {
-        checkType(schema, JPAGVirSchema.class);
-        this.schema = (JPAGVirSchema) schema;
-    }
-
-    @Override
-    public Group getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group group) {
-        checkType(group, JPAGroup.class);
-        this.owner = (JPAGroup) group;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirSchema.java
deleted file mode 100644
index 6f735a8..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGVirSchema.java
+++ /dev/null
@@ -1,36 +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.group;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema;
-
-@Entity
-@Table(name = JPAGVirSchema.TABLE)
-@Cacheable
-public class JPAGVirSchema extends AbstractVirSchema implements GVirSchema {
-
-    private static final long serialVersionUID = -2595041749349652939L;
-
-    public static final String TABLE = "GVirSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
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 20e8808..06bebdb 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
@@ -19,9 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.entity.group;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import javax.persistence.Cacheable;
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
@@ -39,35 +37,31 @@ import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+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.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
+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.anyobject.JPAADynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.validation.entity.GroupCheck;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractSubject;
-import org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
+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;
 
 @Entity
 @Table(name = JPAGroup.TABLE)
 @Cacheable
 @GroupCheck
-public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> implements Group {
+public class JPAGroup extends AbstractAny<GPlainAttr, GDerAttr, GVirAttr> implements Group {
 
     private static final long serialVersionUID = -5281258853142421875L;
 
@@ -88,79 +82,59 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAGPlainAttrTemplate> gAttrTemplates;
+    private List<JPAGPlainAttr> plainAttrs = new ArrayList<>();
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAGDerAttrTemplate> gDerAttrTemplates;
+    private List<JPAGDerAttr> derAttrs = new ArrayList<>();
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPAGVirAttrTemplate> gVirAttrTemplates;
+    private List<JPAGVirAttr> virAttrs = new ArrayList<>();
 
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMPlainAttrTemplate> mAttrTemplates;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMDerAttrTemplate> mDerAttrTemplates;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMVirAttrTemplate> mVirAttrTemplates;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAGPlainAttr> plainAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAGDerAttr> derAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAGVirAttr> virAttrs;
-
-    /**
-     * Provisioning external resources.
-     */
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(joinColumns =
             @JoinColumn(name = "group_id"),
             inverseJoinColumns =
             @JoinColumn(name = "resource_name"))
     @Valid
-    private Set<JPAExternalResource> resources;
+    private List<JPAExternalResource> resources = new ArrayList<>();
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "group_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyTypeClass_name"))
+    private List<JPAAnyTypeClass> auxClasses = new ArrayList<>();
 
     @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "group")
     @Valid
-    private JPADynGroupMembership dynMembership;
+    private JPAADynGroupMembership aDynMembership;
 
-    public JPAGroup() {
-        super();
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "group")
+    @Valid
+    private JPAUDynGroupMembership uDynMembership;
 
-        gAttrTemplates = new ArrayList<>();
-        gDerAttrTemplates = new ArrayList<>();
-        gVirAttrTemplates = new ArrayList<>();
-        mAttrTemplates = new ArrayList<>();
-        mDerAttrTemplates = new ArrayList<>();
-        mVirAttrTemplates = new ArrayList<>();
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "group")
+    private List<JPATypeExtension> typeExtensions = new ArrayList<>();
 
-        plainAttrs = new ArrayList<>();
-        derAttrs = new ArrayList<>();
-        virAttrs = new ArrayList<>();
+    @Override
+    public Long getKey() {
+        return id;
+    }
 
-        resources = new HashSet<>();
+    @Override
+    public AnyType getType() {
+        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findGroup();
     }
 
     @Override
-    public Long getKey() {
-        return id;
+    public void setType(final AnyType type) {
+        // nothing to do
     }
 
     @Override
-    protected Set<JPAExternalResource> internalGetResources() {
+    protected List<JPAExternalResource> internalGetResources() {
         return resources;
     }
 
@@ -197,59 +171,13 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public <T extends AttrTemplate<K>, K extends Schema> List<T> getAttrTemplates(final Class<T> reference) {
-        List<T> result = new ArrayList<>();
-
-        if (GPlainAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) gAttrTemplates;
-        } else if (GDerAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) gDerAttrTemplates;
-        } else if (GVirAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) gVirAttrTemplates;
-        } else if (MPlainAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) mAttrTemplates;
-        } else if (MDerAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) mDerAttrTemplates;
-        } else if (MVirAttrTemplate.class.isAssignableFrom(reference)) {
-            result = (List<T>) mVirAttrTemplates;
-        }
-
-        return result;
-    }
-
-    @Override
-    public <T extends AttrTemplate<K>, K extends Schema> T getAttrTemplate(
-            final Class<T> reference, final String schemaName) {
-
-        return CollectionUtils.find(getAttrTemplates(reference), new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T template) {
-                return schemaName.equals(template.getSchema().getKey());
-            }
-        });
-    }
-
-    @Override
-    public <T extends AttrTemplate<K>, K extends Schema> List<K> getAttrTemplateSchemas(final Class<T> reference) {
-        return CollectionUtils.collect(getAttrTemplates(reference), new Transformer<T, K>() {
-
-            @Override
-            public K transform(final T input) {
-                return input.getSchema();
-            }
-        }, new ArrayList<K>());
-    }
-
-    @Override
-    public boolean addPlainAttr(final GPlainAttr attr) {
+    public boolean add(final GPlainAttr attr) {
         checkType(attr, JPAGPlainAttr.class);
         return plainAttrs.add((JPAGPlainAttr) attr);
     }
 
     @Override
-    public boolean removePlainAttr(final GPlainAttr attr) {
+    public boolean remove(final GPlainAttr attr) {
         checkType(attr, JPAGPlainAttr.class);
         return plainAttrs.remove((JPAGPlainAttr) attr);
     }
@@ -260,13 +188,13 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
     }
 
     @Override
-    public boolean addDerAttr(final GDerAttr attr) {
+    public boolean add(final GDerAttr attr) {
         checkType(attr, JPAGDerAttr.class);
         return derAttrs.add((JPAGDerAttr) attr);
     }
 
     @Override
-    public boolean removeDerAttr(final GDerAttr attr) {
+    public boolean remove(final GDerAttr attr) {
         checkType(attr, JPAGDerAttr.class);
         return derAttrs.remove((JPAGDerAttr) attr);
     }
@@ -277,13 +205,13 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
     }
 
     @Override
-    public boolean addVirAttr(final GVirAttr attr) {
+    public boolean add(final GVirAttr attr) {
         checkType(attr, JPAGVirAttr.class);
         return virAttrs.add((JPAGVirAttr) attr);
     }
 
     @Override
-    public boolean removeVirAttr(final GVirAttr attr) {
+    public boolean remove(final GVirAttr attr) {
         checkType(attr, JPAGVirAttr.class);
         return virAttrs.remove((JPAGVirAttr) attr);
     }
@@ -294,14 +222,70 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
     }
 
     @Override
-    public DynGroupMembership getDynMembership() {
-        return dynMembership;
+    public ADynGroupMembership getADynMembership() {
+        return aDynMembership;
+    }
+
+    @Override
+    public void setADynMembership(final ADynGroupMembership aDynMembership) {
+        checkType(aDynMembership, JPAADynGroupMembership.class);
+        this.aDynMembership = (JPAADynGroupMembership) aDynMembership;
+    }
+
+    @Override
+    public UDynGroupMembership getUDynMembership() {
+        return uDynMembership;
+    }
+
+    @Override
+    public void setUDynMembership(final UDynGroupMembership uDynMembership) {
+        checkType(aDynMembership, JPAADynGroupMembership.class);
+        this.uDynMembership = (JPAUDynGroupMembership) uDynMembership;
+    }
+
+    @Override
+    public boolean add(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.add((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getAuxClasses() {
+        return auxClasses;
+    }
+
+    @Override
+    public boolean add(final TypeExtension typeExtension) {
+        checkType(typeExtension, JPATypeExtension.class);
+        return this.typeExtensions.add((JPATypeExtension) typeExtension);
+    }
+
+    @Override
+    public boolean remove(final TypeExtension typeExtension) {
+        checkType(typeExtension, JPATypeExtension.class);
+        return this.typeExtensions.remove((JPATypeExtension) typeExtension);
+    }
+
+    @Override
+    public TypeExtension getTypeExtension(final AnyType anyType) {
+        return CollectionUtils.find(typeExtensions, new Predicate<TypeExtension>() {
+
+            @Override
+            public boolean evaluate(final TypeExtension typeExtension) {
+                return typeExtension.getAnyType().equals(anyType);
+            }
+        });
     }
 
     @Override
-    public void setDynMembership(final DynGroupMembership dynMembership) {
-        checkType(dynMembership, JPADynGroupMembership.class);
-        this.dynMembership = (JPADynGroupMembership) dynMembership;
+    public List<? extends TypeExtension> getTypeExtensions() {
+        return typeExtensions;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
new file mode 100644
index 0000000..69fe3be
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java
@@ -0,0 +1,108 @@
+/*
+ * 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.group;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+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.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+
+@Entity
+@Table(name = JPATypeExtension.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "group_id", "anyType_name" }))
+public class JPATypeExtension extends AbstractEntity<Long> implements TypeExtension {
+
+    private static final long serialVersionUID = -8367626793791263551L;
+
+    public static final String TABLE = "TypeExtension";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAGroup group;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "typeExtension_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "anyTypeClass_name"))
+    private List<JPAAnyTypeClass> auxClasses = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Group getGroup() {
+        return group;
+    }
+
+    @Override
+    public void setGroup(final Group group) {
+        checkType(group, JPAGroup.class);
+        this.group = (JPAGroup) group;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public boolean add(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.add((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public boolean remove(final AnyTypeClass auxClass) {
+        checkType(auxClass, JPAAnyTypeClass.class);
+        return this.auxClasses.remove((JPAAnyTypeClass) auxClass);
+    }
+
+    @Override
+    public List<? extends AnyTypeClass> getAuxClasses() {
+        return auxClasses;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttr.java
deleted file mode 100644
index 698f68c..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttr.java
+++ /dev/null
@@ -1,82 +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.membership;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
-
-@Entity
-@Table(name = JPAMDerAttr.TABLE)
-public class JPAMDerAttr extends AbstractDerAttr implements MDerAttr {
-
-    private static final long serialVersionUID = -443509121923448129L;
-
-    public static final String TABLE = "MDerAttr";
-
-    @ManyToOne
-    private JPAMembership owner;
-
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAMDerAttrTemplate template;
-
-    @Override
-    public Membership getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
-        checkType(owner, JPAMembership.class);
-        this.owner = (JPAMembership) owner;
-    }
-
-    @Override
-    public MDerAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final MDerAttrTemplate template) {
-        checkType(template, JPAMDerAttrTemplate.class);
-        this.template = (JPAMDerAttrTemplate) template;
-    }
-
-    @Override
-    public MDerSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final DerSchema schema) {
-        LOG.warn("This is membership attribute, set template to select schema");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
deleted file mode 100644
index 2139cd5..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
+++ /dev/null
@@ -1,67 +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.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-
-@Entity
-@Table(name = JPAMDerAttrTemplate.TABLE)
-public class JPAMDerAttrTemplate extends AbstractDerAttrTemplate<MDerSchema> implements MDerAttrTemplate {
-
-    private static final long serialVersionUID = -4465930976210263434L;
-
-    public static final String TABLE = "MDerAttrTemplate";
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAMDerSchema schema;
-
-    @Override
-    public MDerSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final MDerSchema schema) {
-        checkType(schema, JPAMDerSchema.class);
-        this.schema = (JPAMDerSchema) schema;
-    }
-
-    @Override
-    public Group getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group owner) {
-        checkType(owner, JPAGroup.class);
-        this.owner = (JPAGroup) owner;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerSchema.java
deleted file mode 100644
index e6711d6..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMDerSchema.java
+++ /dev/null
@@ -1,34 +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.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-
-@Entity
-@Table(name = JPAMDerSchema.TABLE)
-public class JPAMDerSchema extends AbstractDerSchema implements MDerSchema {
-
-    private static final long serialVersionUID = -4694082505732174583L;
-
-    public static final String TABLE = "MDerSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttr.java
deleted file mode 100644
index a6c19ff..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttr.java
+++ /dev/null
@@ -1,141 +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.membership;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.validation.Valid;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-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.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
-
-@Entity
-@Table(name = JPAMPlainAttr.TABLE)
-public class JPAMPlainAttr extends AbstractPlainAttr implements MPlainAttr {
-
-    private static final long serialVersionUID = 3755864809152866489L;
-
-    public static final String TABLE = "MPlainAttr";
-
-    @Id
-    private Long id;
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAMembership owner;
-
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAMPlainAttrTemplate template;
-
-    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
-    @Valid
-    private List<JPAMPlainAttrValue> values;
-
-    @OneToOne(cascade = CascadeType.ALL, mappedBy = "attribute")
-    @Valid
-    private JPAMPlainAttrUniqueValue uniqueValue;
-
-    public JPAMPlainAttr() {
-        super();
-        values = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Membership getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
-        checkType(owner, JPAMembership.class);
-        this.owner = (JPAMembership) owner;
-    }
-
-    @Override
-    public MPlainAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final MPlainAttrTemplate template) {
-        checkType(template, JPAMPlainAttrTemplate.class);
-        this.template = (JPAMPlainAttrTemplate) template;
-    }
-
-    @Override
-    public MPlainSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        LOG.warn("This is membership attribute, set template to select schema");
-    }
-
-    @Override
-    protected boolean addValue(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPAMPlainAttrValue.class);
-        return values.add((JPAMPlainAttrValue) attrValue);
-    }
-
-    @Override
-    public boolean removeValue(final PlainAttrValue attrValue) {
-        checkType(attrValue, JPAMPlainAttrValue.class);
-        return values.remove((JPAMPlainAttrValue) attrValue);
-    }
-
-    @Override
-    public List<? extends MPlainAttrValue> getValues() {
-        return values;
-    }
-
-    @Override
-    public MPlainAttrUniqueValue getUniqueValue() {
-        return uniqueValue;
-    }
-
-    @Override
-    public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) {
-        checkType(owner, JPAMPlainAttrUniqueValue.class);
-        this.uniqueValue = (JPAMPlainAttrUniqueValue) uniqueValue;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
deleted file mode 100644
index 7b43ec7..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
+++ /dev/null
@@ -1,77 +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.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-
-@Entity
-@Table(name = JPAMPlainAttrTemplate.TABLE)
-public class JPAMPlainAttrTemplate extends AbstractPlainAttrTemplate<MPlainSchema> implements MPlainAttrTemplate {
-
-    private static final long serialVersionUID = -8768086609963244514L;
-
-    public static final String TABLE = "MPlainAttrTemplate";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAMPlainSchema schema;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public MPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final MPlainSchema schema) {
-        checkType(schema, JPAMPlainSchema.class);
-        this.schema = (JPAMPlainSchema) schema;
-    }
-
-    @Override
-    public JPAGroup getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group owner) {
-        checkType(owner, JPAGroup.class);
-        this.owner = (JPAGroup) owner;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrUniqueValue.java
deleted file mode 100644
index 3bf92ce..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrUniqueValue.java
+++ /dev/null
@@ -1,78 +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.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
-
-@Entity
-@Table(name = JPAMPlainAttrUniqueValue.TABLE)
-public class JPAMPlainAttrUniqueValue extends AbstractPlainAttrValue implements MPlainAttrUniqueValue {
-
-    private static final long serialVersionUID = 3985867531873453718L;
-
-    public static final String TABLE = "MPlainAttrUniqueValue";
-
-    @Id
-    private Long id;
-
-    @OneToOne(optional = false)
-    private JPAMPlainAttr attribute;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "schema_name")
-    private JPAMPlainSchema schema;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public MPlainAttr getAttr() {
-        return attribute;
-    }
-
-    @Override
-    public void setAttr(final PlainAttr attr) {
-        checkType(attr, JPAMPlainAttr.class);
-        this.attribute = (JPAMPlainAttr) attr;
-    }
-
-    @Override
-    public MPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPAMPlainSchema.class);
-        this.schema = (JPAMPlainSchema) schema;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrValue.java
deleted file mode 100644
index 0327211..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainAttrValue.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.jpa.entity.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.validation.constraints.NotNull;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
-
-@Entity
-@Table(name = JPAMPlainAttrValue.TABLE)
-@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
-public class JPAMPlainAttrValue extends AbstractPlainAttrValue implements MPlainAttrValue {
-
-    private static final long serialVersionUID = -7188881172631198385L;
-
-    public static final String TABLE = "MPlainAttrValue";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    @NotNull
-    private JPAMPlainAttr attribute;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public MPlainAttr getAttr() {
-        return attribute;
-    }
-
-    @Override
-    public void setAttr(final PlainAttr attr) {
-        checkType(attr, JPAMPlainAttr.class);
-        this.attribute = (JPAMPlainAttr) attr;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainSchema.java
deleted file mode 100644
index fd000d6..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMPlainSchema.java
+++ /dev/null
@@ -1,36 +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.membership;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
-
-@Entity
-@Table(name = JPAMPlainSchema.TABLE)
-@Cacheable
-public class JPAMPlainSchema extends AbstractPlainSchema implements MPlainSchema {
-
-    private static final long serialVersionUID = -8053736450044590651L;
-
-    public static final String TABLE = "MPlainSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttr.java
deleted file mode 100644
index ba7fe06..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttr.java
+++ /dev/null
@@ -1,81 +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.membership;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
-
-@Entity
-@Table(name = JPAMVirAttr.TABLE)
-public class JPAMVirAttr extends AbstractVirAttr implements MVirAttr {
-
-    private static final long serialVersionUID = 7774760571251641332L;
-
-    public static final String TABLE = "MVirAttr";
-
-    @ManyToOne
-    private JPAMembership owner;
-
-    @Column(nullable = false)
-    @OneToOne(cascade = CascadeType.MERGE)
-    private JPAMVirAttrTemplate template;
-
-    @Override
-    public Membership getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
-        checkType(owner, JPAMembership.class);
-        this.owner = (JPAMembership) owner;
-    }
-
-    @Override
-    public MVirAttrTemplate getTemplate() {
-        return template;
-    }
-
-    @Override
-    public void setTemplate(final MVirAttrTemplate template) {
-        checkType(template, JPAMVirAttrTemplate.class);
-        this.template = (JPAMVirAttrTemplate) template;
-    }
-
-    @Override
-    public MVirSchema getSchema() {
-        return template == null ? null : template.getSchema();
-    }
-
-    @Override
-    public void setSchema(final VirSchema schema) {
-        LOG.warn("This is membership attribute, set template to select schema");
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
deleted file mode 100644
index da84c4d..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
+++ /dev/null
@@ -1,67 +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.membership;
-
-import javax.persistence.Entity;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-
-@Entity
-@Table(name = JPAMVirAttrTemplate.TABLE)
-public class JPAMVirAttrTemplate extends AbstractVirAttrTemplate<MVirSchema> implements MVirAttrTemplate {
-
-    private static final long serialVersionUID = 6618560912535667392L;
-
-    public static final String TABLE = "MVirAttrTemplate";
-
-    @ManyToOne
-    private JPAGroup owner;
-
-    @ManyToOne
-    @JoinColumn(name = "schema_name")
-    private JPAMVirSchema schema;
-
-    @Override
-    public MVirSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final MVirSchema schema) {
-        checkType(schema, JPAMVirSchema.class);
-        this.schema = (JPAMVirSchema) schema;
-    }
-
-    @Override
-    public Group getOwner() {
-        return owner;
-    }
-
-    @Override
-    public void setOwner(final Group group) {
-        checkType(group, JPAGroup.class);
-        this.owner = (JPAGroup) group;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirSchema.java
deleted file mode 100644
index 589ec6e..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMVirSchema.java
+++ /dev/null
@@ -1,36 +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.membership;
-
-import javax.persistence.Cacheable;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema;
-
-@Entity
-@Table(name = JPAMVirSchema.TABLE)
-@Cacheable
-public class JPAMVirSchema extends AbstractVirSchema implements MVirSchema {
-
-    private static final long serialVersionUID = 6255905733563668766L;
-
-    public static final String TABLE = "MVirSchema";
-
-}


[20/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
new file mode 100644
index 0000000..d91b948
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -0,0 +1,811 @@
+/*
+ * 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.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Entity;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import javax.validation.ValidationException;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.ReflectionUtils;
+
+@Repository
+public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements AnySearchDAO {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AnySearchDAO.class);
+
+    private static final String EMPTY_ATTR_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private PlainSchemaDAO schemaDAO;
+
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
+    private String getAdminRealmsFilter(final Set<String> adminRealms, final SearchSupport svs) {
+        Set<Long> realmKeys = new HashSet<>();
+        for (String realmPath : RealmUtils.normalize(adminRealms)) {
+            Realm realm = realmDAO.find(realmPath);
+            if (realm == null) {
+                LOG.warn("Ignoring invalid realm {}", realmPath);
+            } else {
+                CollectionUtils.collect(realmDAO.findDescendants(realm), new Transformer<Realm, Long>() {
+
+                    @Override
+                    public Long transform(final Realm descendant) {
+                        return descendant.getKey();
+                    }
+                }, realmKeys);
+            }
+        }
+
+        StringBuilder adminRealmFilter = new StringBuilder().
+                append("SELECT any_id FROM ").append(svs.field().name).
+                append(" WHERE realm_id IN (SELECT id AS realm_id FROM Realm");
+
+        boolean firstRealm = true;
+        for (Long realmKey : realmKeys) {
+            if (firstRealm) {
+                adminRealmFilter.append(" WHERE");
+                firstRealm = false;
+            } else {
+                adminRealmFilter.append(" OR");
+            }
+            adminRealmFilter.append(" id = ").append(realmKey);
+        }
+
+        adminRealmFilter.append(')');
+
+        return adminRealmFilter.toString();
+    }
+
+    @Override
+    public int count(final Set<String> adminRealms, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+        // 1. get the query string from the search condition
+        SearchSupport svs = new SearchSupport(typeKind);
+        StringBuilder queryString = getQuery(searchCondition, parameters, typeKind, svs);
+
+        // 2. take into account administrative realms
+        queryString.insert(0, "SELECT u.any_id FROM (");
+        queryString.append(") u WHERE any_id IN (");
+        queryString.append(getAdminRealmsFilter(adminRealms, svs)).append(')');
+
+        // 3. prepare the COUNT query
+        queryString.insert(0, "SELECT COUNT(any_id) FROM (");
+        queryString.append(") count_any_id");
+
+        Query countQuery = entityManager.createNativeQuery(queryString.toString());
+        fillWithParameters(countQuery, parameters);
+
+        return ((Number) countQuery.getSingleResult()).intValue();
+    }
+
+    @Override
+    public <T extends Any<?, ?, ?>> List<T> search(
+            final Set<String> adminRealms, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+
+        return search(adminRealms, searchCondition, Collections.<OrderByClause>emptyList(), typeKind);
+    }
+
+    @Override
+    public <T extends Any<?, ?, ?>> List<T> search(
+            final Set<String> adminRealms, final SearchCond searchCondition, final List<OrderByClause> orderBy,
+            final AnyTypeKind typeKind) {
+
+        return search(adminRealms, searchCondition, -1, -1, orderBy, typeKind);
+    }
+
+    @Override
+    public <T extends Any<?, ?, ?>> List<T> search(
+            final Set<String> adminRealms, final SearchCond searchCondition, final int page, final int itemsPerPage,
+            final List<OrderByClause> orderBy, final AnyTypeKind typeKind) {
+
+        List<T> result = Collections.<T>emptyList();
+
+        if (adminRealms != null && !adminRealms.isEmpty()) {
+            LOG.debug("Search condition:\n{}", searchCondition);
+
+            if (searchCondition != null && searchCondition.isValid()) {
+                try {
+                    result = doSearch(adminRealms, searchCondition, page, itemsPerPage, orderBy, typeKind);
+                } catch (Exception e) {
+                    LOG.error("While searching for {}", typeKind, e);
+                }
+            } else {
+                LOG.error("Invalid search condition:\n{}", searchCondition);
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends Any<?, ?, ?>> boolean matches(
+            final T subject, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+
+        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+        // 1. get the query string from the search condition
+        SearchSupport svs = new SearchSupport(typeKind);
+        StringBuilder queryString = getQuery(searchCondition, parameters, typeKind, svs);
+
+        boolean matches;
+        if (queryString.length() == 0) {
+            // Could be empty: got into a group search with a single membership condition ...
+            matches = false;
+        } else {
+            // 2. take into account the passed user
+            queryString.insert(0, "SELECT u.any_id FROM (");
+            queryString.append(") u WHERE any_id=?").append(setParameter(parameters, subject.getKey()));
+
+            // 3. prepare the search query
+            Query query = entityManager.createNativeQuery(queryString.toString());
+
+            // 4. populate the search query with parameter values
+            fillWithParameters(query, parameters);
+
+            // 5. executes query
+            matches = !query.getResultList().isEmpty();
+        }
+
+        return matches;
+    }
+
+    private int setParameter(final List<Object> parameters, final Object parameter) {
+        int key;
+        synchronized (parameters) {
+            parameters.add(parameter);
+            key = parameters.size();
+        }
+
+        return key;
+    }
+
+    private void fillWithParameters(final Query query, final List<Object> parameters) {
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) instanceof Date) {
+                query.setParameter(i + 1, (Date) parameters.get(i), TemporalType.TIMESTAMP);
+            } else if (parameters.get(i) instanceof Boolean) {
+                query.setParameter(i + 1, ((Boolean) parameters.get(i))
+                        ? 1
+                        : 0);
+            } else {
+                query.setParameter(i + 1, parameters.get(i));
+            }
+        }
+    }
+
+    private StringBuilder buildSelect(final OrderBySupport orderBySupport) {
+        final StringBuilder select = new StringBuilder("SELECT u.any_id");
+
+        for (OrderBySupport.Item obs : orderBySupport.items) {
+            select.append(',').append(obs.select);
+        }
+        select.append(" FROM ");
+
+        return select;
+    }
+
+    private StringBuilder buildWhere(final OrderBySupport orderBySupport) {
+        final StringBuilder where = new StringBuilder(" u");
+        for (SearchSupport.SearchView searchView : orderBySupport.views) {
+            where.append(',').append(searchView.name).append(' ').append(searchView.alias);
+        }
+        where.append(" WHERE ");
+        for (SearchSupport.SearchView searchView : orderBySupport.views) {
+            where.append("u.any_id=").append(searchView.alias).append(".any_id AND ");
+        }
+
+        for (OrderBySupport.Item obs : orderBySupport.items) {
+            if (StringUtils.isNotBlank(obs.where)) {
+                where.append(obs.where).append(" AND ");
+            }
+        }
+        where.append("u.any_id IN (");
+
+        return where;
+    }
+
+    private StringBuilder buildOrderBy(final OrderBySupport orderBySupport) {
+        final StringBuilder orderBy = new StringBuilder();
+
+        for (OrderBySupport.Item obs : orderBySupport.items) {
+            orderBy.append(obs.orderBy).append(',');
+        }
+        if (!orderBySupport.items.isEmpty()) {
+            orderBy.insert(0, " ORDER BY ");
+            orderBy.deleteCharAt(orderBy.length() - 1);
+        }
+
+        return orderBy;
+    }
+
+    private OrderBySupport parseOrderBy(final AnyTypeKind type, final SearchSupport svs,
+            final List<OrderByClause> orderByClauses) {
+
+        final AnyUtils attrUtils = anyUtilsFactory.getInstance(type);
+
+        OrderBySupport orderBySupport = new OrderBySupport();
+
+        for (OrderByClause clause : orderByClauses) {
+            OrderBySupport.Item obs = new OrderBySupport.Item();
+
+            // Manage difference among external key attribute and internal JPA @Id
+            String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
+
+            Field subjectField = ReflectionUtils.findField(attrUtils.anyClass(), fieldName);
+            if (subjectField == null) {
+                PlainSchema schema = schemaDAO.find(fieldName);
+                if (schema != null) {
+                    if (schema.isUniqueConstraint()) {
+                        orderBySupport.views.add(svs.uniqueAttr());
+
+                        obs.select = new StringBuilder().
+                                append(svs.uniqueAttr().alias).append('.').append(svs.fieldName(schema.getType())).
+                                append(" AS ").append(fieldName).toString();
+                        obs.where = new StringBuilder().
+                                append(svs.uniqueAttr().alias).
+                                append(".schema_name='").append(fieldName).append("'").toString();
+                        obs.orderBy = fieldName + " " + clause.getDirection().name();
+                    } else {
+                        orderBySupport.views.add(svs.attr());
+
+                        obs.select = new StringBuilder().
+                                append(svs.attr().alias).append('.').append(svs.fieldName(schema.getType())).
+                                append(" AS ").append(fieldName).toString();
+                        obs.where = new StringBuilder().
+                                append(svs.attr().alias).
+                                append(".schema_name='").append(fieldName).append("'").toString();
+                        obs.orderBy = fieldName + " " + clause.getDirection().name();
+                    }
+                }
+            } else {
+                orderBySupport.views.add(svs.field());
+
+                obs.select = svs.field().alias + "." + fieldName;
+                obs.where = StringUtils.EMPTY;
+                obs.orderBy = svs.field().alias + "." + fieldName + " " + clause.getDirection().name();
+            }
+
+            if (obs.isEmpty()) {
+                LOG.warn("Cannot build any valid clause from {}", clause);
+            } else {
+                orderBySupport.items.add(obs);
+            }
+        }
+
+        return orderBySupport;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T extends Any<?, ?, ?>> List<T> doSearch(final Set<String> adminRealms,
+            final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy,
+            final AnyTypeKind typeKind) {
+
+        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+        // 1. get the query string from the search condition
+        SearchSupport svs = new SearchSupport(typeKind);
+        StringBuilder queryString = getQuery(nodeCond, parameters, typeKind, svs);
+
+        // 2. take into account administrative groups and ordering
+        OrderBySupport orderBySupport = parseOrderBy(typeKind, svs, orderBy);
+        if (queryString.charAt(0) == '(') {
+            queryString.insert(0, buildSelect(orderBySupport));
+            queryString.append(buildWhere(orderBySupport));
+        } else {
+            queryString.insert(0, buildSelect(orderBySupport).append('('));
+            queryString.append(')').append(buildWhere(orderBySupport));
+        }
+        queryString.
+                append(getAdminRealmsFilter(adminRealms, svs)).append(')').
+                append(buildOrderBy(orderBySupport));
+
+        // 3. prepare the search query
+        Query query = entityManager.createNativeQuery(queryString.toString());
+
+        // 4. page starts from 1, while setFirtResult() starts from 0
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+
+        if (itemsPerPage >= 0) {
+            query.setMaxResults(itemsPerPage);
+        }
+
+        // 5. populate the search query with parameter values
+        fillWithParameters(query, parameters);
+
+        // 6. Prepare the result (avoiding duplicates)
+        List<T> result = new ArrayList<>();
+
+        for (Object subjectKey : query.getResultList()) {
+            long actualKey;
+            if (subjectKey instanceof Object[]) {
+                actualKey = ((Number) ((Object[]) subjectKey)[0]).longValue();
+            } else {
+                actualKey = ((Number) subjectKey).longValue();
+            }
+
+            T subject = typeKind == AnyTypeKind.USER
+                    ? (T) userDAO.find(actualKey)
+                    : typeKind == AnyTypeKind.GROUP
+                            ? (T) groupDAO.find(actualKey)
+                            : (T) anyObjectDAO.find(actualKey);
+            if (subject == null) {
+                LOG.error("Could not find {} with id {}, even though returned by the native query",
+                        typeKind, actualKey);
+            } else {
+                if (!result.contains(subject)) {
+                    result.add(subject);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters,
+            final AnyTypeKind type, final SearchSupport svs) {
+
+        StringBuilder query = new StringBuilder();
+
+        switch (nodeCond.getType()) {
+
+            case LEAF:
+            case NOT_LEAF:
+                if (nodeCond.getRelationshipCond() != null
+                        && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+
+                    query.append(getQuery(nodeCond.getRelationshipCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+                }
+                if (nodeCond.getMembershipCond() != null
+                        && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+
+                    query.append(getQuery(nodeCond.getMembershipCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+                }
+                if (nodeCond.getRoleCond() != null && AnyTypeKind.USER == type) {
+                    query.append(getQuery(nodeCond.getRoleCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+                }
+                if (nodeCond.getResourceCond() != null) {
+                    query.append(getQuery(nodeCond.getResourceCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+                }
+                if (nodeCond.getAttributeCond() != null) {
+                    query.append(getQuery(nodeCond.getAttributeCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+                }
+                if (nodeCond.getAnyCond() != null) {
+                    query.append(getQuery(nodeCond.getAnyCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+                }
+                break;
+
+            case AND:
+                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+                        append(" AND any_id IN ( ").
+                        append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+                        append(")");
+                break;
+
+            case OR:
+                query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+                        append(" OR any_id IN ( ").
+                        append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+                        append(")");
+                break;
+
+            default:
+        }
+
+        return query;
+    }
+
+    private String getQuery(final RelationshipCond cond, final boolean not, final List<Object> parameters,
+            final SearchSupport svs) {
+
+        StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE ");
+
+        if (not) {
+            query.append("any_id NOT IN (");
+        } else {
+            query.append("any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id ").append("FROM ").
+                append(svs.relationship().name).append(" WHERE ").
+                append("right_anyObject_id=?").append(setParameter(parameters, cond.getAnyObjectKey())).
+                append(')');
+
+        return query.toString();
+    }
+
+    private String getQuery(final MembershipCond cond, final boolean not, final List<Object> parameters,
+            final SearchSupport svs) {
+
+        StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE ");
+
+        if (not) {
+            query.append("any_id NOT IN (");
+        } else {
+            query.append("any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id ").append("FROM ").
+                append(svs.membership().name).append(" WHERE ").
+                append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
+                append(')');
+
+        if (not) {
+            query.append("AND any_id NOT IN (");
+        } else {
+            query.append("OR any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id ").append("FROM ").
+                append(svs.dyngroupmembership().name).append(" WHERE ").
+                append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
+                append(')');
+
+        return query.toString();
+    }
+
+    private String getQuery(final RoleCond cond, final boolean not, final List<Object> parameters,
+            final SearchSupport svs) {
+
+        StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE ");
+
+        if (not) {
+            query.append("any_id NOT IN (");
+        } else {
+            query.append("any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id ").append("FROM ").
+                append(svs.role().name).append(" WHERE ").
+                append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+                append(')');
+
+        if (not) {
+            query.append("AND any_id NOT IN (");
+        } else {
+            query.append("OR any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id ").append("FROM ").
+                append(svs.dynrolemembership().name).append(" WHERE ").
+                append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+                append(')');
+
+        return query.toString();
+    }
+
+    private String getQuery(final ResourceCond cond, final boolean not, final List<Object> parameters,
+            final AnyTypeKind typeKind, final SearchSupport svs) {
+
+        final StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE ");
+
+        if (not) {
+            query.append("any_id NOT IN (");
+        } else {
+            query.append("any_id IN (");
+        }
+
+        query.append("SELECT DISTINCT any_id FROM ").
+                append(svs.resource().name).
+                append(" WHERE resource_name=?").
+                append(setParameter(parameters, cond.getResourceName()));
+
+        if (typeKind == AnyTypeKind.USER) {
+            query.append(" UNION SELECT DISTINCT any_id FROM ").
+                    append(svs.groupResource().name).
+                    append(" WHERE resource_name=?").
+                    append(setParameter(parameters, cond.getResourceName()));
+        }
+
+        query.append(')');
+
+        return query.toString();
+    }
+
+    private void fillAttributeQuery(final StringBuilder query, final PlainAttrValue attrValue,
+            final PlainSchema schema, final AttributeCond cond, final boolean not,
+            final List<Object> parameters, final SearchSupport svs) {
+
+        String column = (cond instanceof AnyCond)
+                ? cond.getSchema()
+                : "' AND " + svs.fieldName(schema.getType());
+
+        switch (cond.getType()) {
+
+            case ISNULL:
+                query.append(column).append(not
+                        ? " IS NOT NULL"
+                        : " IS NULL");
+                break;
+
+            case ISNOTNULL:
+                query.append(column).append(not
+                        ? " IS NULL"
+                        : " IS NOT NULL");
+                break;
+
+            case LIKE:
+                if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
+                    query.append(column);
+                    if (not) {
+                        query.append(" NOT ");
+                    }
+                    query.append(" LIKE ?").append(setParameter(parameters, cond.getExpression()));
+                } else {
+                    if (!(cond instanceof AnyCond)) {
+                        query.append("' AND");
+                    }
+                    query.append(" 1=2");
+                    LOG.error("LIKE is only compatible with string or enum schemas");
+                }
+                break;
+
+            case EQ:
+                query.append(column);
+                if (not) {
+                    query.append("<>");
+                } else {
+                    query.append('=');
+                }
+                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                break;
+
+            case GE:
+                query.append(column);
+                if (not) {
+                    query.append('<');
+                } else {
+                    query.append(">=");
+                }
+                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                break;
+
+            case GT:
+                query.append(column);
+                if (not) {
+                    query.append("<=");
+                } else {
+                    query.append('>');
+                }
+                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                break;
+
+            case LE:
+                query.append(column);
+                if (not) {
+                    query.append('>');
+                } else {
+                    query.append("<=");
+                }
+                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                break;
+
+            case LT:
+                query.append(column);
+                if (not) {
+                    query.append(">=");
+                } else {
+                    query.append('<');
+                }
+                query.append('?').append(setParameter(parameters, attrValue.getValue()));
+                break;
+
+            default:
+        }
+    }
+
+    private String getQuery(final AttributeCond cond, final boolean not, final List<Object> parameters,
+            final AnyTypeKind typeKind, final SearchSupport svs) {
+
+        AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+
+        PlainSchema schema = schemaDAO.find(cond.getSchema());
+        if (schema == null) {
+            LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
+            return EMPTY_ATTR_QUERY;
+        }
+
+        PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+        try {
+            if (cond.getType() != AttributeCond.Type.LIKE && cond.getType() != AttributeCond.Type.ISNULL
+                    && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+
+                schema.getValidator().validate(cond.getExpression(), attrValue);
+            }
+        } catch (ValidationException e) {
+            LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+            return EMPTY_ATTR_QUERY;
+        }
+
+        StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ");
+        if (cond.getType() == AttributeCond.Type.ISNOTNULL) {
+            query.append(svs.field().name).
+                    append(" WHERE any_id NOT IN (SELECT any_id FROM ").
+                    append(svs.nullAttr().name).
+                    append(" WHERE schema_name='").append(schema.getKey()).append("')");
+        } else {
+            if (cond.getType() == AttributeCond.Type.ISNULL) {
+                query.append(svs.nullAttr().name).
+                        append(" WHERE schema_name='").append(schema.getKey()).append("'");
+            } else {
+                if (schema.isUniqueConstraint()) {
+                    query.append(svs.uniqueAttr().name);
+                } else {
+                    query.append(svs.attr().name);
+                }
+                query.append(" WHERE schema_name='").append(schema.getKey());
+
+                fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+            }
+        }
+
+        return query.toString();
+    }
+
+    @SuppressWarnings("rawtypes")
+    private String getQuery(final AnyCond cond, final boolean not, final List<Object> parameters,
+            final AnyTypeKind typeKind, final SearchSupport svs) {
+
+        AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+
+        // Keeps track of difference between entity's getKey() and JPA @Id fields
+        if ("key".equals(cond.getSchema())) {
+            cond.setSchema("id");
+        }
+
+        Field subjectField = ReflectionUtils.findField(attrUtils.anyClass(), cond.getSchema());
+        if (subjectField == null) {
+            LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
+            return EMPTY_ATTR_QUERY;
+        }
+
+        PlainSchema schema = new JPAPlainSchema();
+        schema.setKey(subjectField.getName());
+        for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
+            if (subjectField.getType().isAssignableFrom(attrSchemaType.getType())) {
+                schema.setType(attrSchemaType);
+            }
+        }
+
+        // Deal with subject Integer fields logically mapping to boolean values
+        // (JPAGroup.inheritPlainAttrs, for example)
+        boolean foundBooleanMin = false;
+        boolean foundBooleanMax = false;
+        if (Integer.class.equals(subjectField.getType())) {
+            for (Annotation annotation : subjectField.getAnnotations()) {
+                if (Min.class.equals(annotation.annotationType())) {
+                    foundBooleanMin = ((Min) annotation).value() == 0;
+                } else if (Max.class.equals(annotation.annotationType())) {
+                    foundBooleanMax = ((Max) annotation).value() == 1;
+                }
+            }
+        }
+        if (foundBooleanMin && foundBooleanMax) {
+            schema.setType(AttrSchemaType.Boolean);
+        }
+
+        // Deal with subject fields representing relationships to other entities
+        if (subjectField.getType().getAnnotation(Entity.class) != null) {
+            Method relMethod = null;
+            try {
+                relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
+            } catch (Exception e) {
+                LOG.error("Could not find {}#getKey", subjectField.getType(), e);
+            }
+
+            if (relMethod != null) {
+                if (Long.class.isAssignableFrom(relMethod.getReturnType())) {
+                    cond.setSchema(cond.getSchema() + "_id");
+                    schema.setType(AttrSchemaType.Long);
+                }
+                if (String.class.isAssignableFrom(relMethod.getReturnType())) {
+                    cond.setSchema(cond.getSchema() + "_name");
+                    schema.setType(AttrSchemaType.String);
+                }
+            }
+        }
+
+        PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+        if (cond.getType() != AttributeCond.Type.LIKE
+                && cond.getType() != AttributeCond.Type.ISNULL
+                && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+
+            try {
+                schema.getValidator().validate(cond.getExpression(), attrValue);
+            } catch (ValidationException e) {
+                LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+                return EMPTY_ATTR_QUERY;
+            }
+        }
+
+        final StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+                append(svs.field().name).append(" WHERE ");
+
+        fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+
+        return query.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..4d82d31
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implements AnyTypeClassDAO {
+
+    @Override
+    public AnyTypeClass find(final String key) {
+        return entityManager.find(JPAAnyTypeClass.class, key);
+    }
+
+    @Override
+    public List<AnyTypeClass> findAll() {
+        TypedQuery<AnyTypeClass> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAAnyTypeClass.class.getSimpleName() + " e ", AnyTypeClass.class);
+        return query.getResultList();
+    }
+
+    @Override
+    public AnyTypeClass save(final AnyTypeClass anyTypeClass) {
+        return entityManager.merge(anyTypeClass);
+    }
+
+    @Override
+    public void delete(final String key) {
+        AnyTypeClass anyTypeClass = find(key);
+        if (anyTypeClass == null) {
+            return;
+        }
+
+        entityManager.remove(anyTypeClass);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
new file mode 100644
index 0000000..bbbf859
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTypeDAO {
+
+    @Override
+    public AnyType find(final String key) {
+        return entityManager.find(JPAAnyType.class, key);
+    }
+
+    private AnyType find(final AnyTypeKind typeKind) {
+        AnyType anyType = find(typeKind.name());
+        if (anyType == null) {
+            anyType = new JPAAnyType();
+            anyType.setKey(typeKind.name());
+            anyType.setKind(typeKind);
+            anyType = save(anyType);
+        }
+        return anyType;
+    }
+
+    @Transactional(readOnly = false)
+    @Override
+    public AnyType findUser() {
+        return find(AnyTypeKind.USER);
+    }
+
+    @Transactional(readOnly = false)
+    @Override
+    public AnyType findGroup() {
+        return find(AnyTypeKind.GROUP);
+    }
+
+    @Override
+    public List<AnyType> findAll() {
+        TypedQuery<AnyType> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAAnyType.class.getSimpleName() + " e ", AnyType.class);
+        return query.getResultList();
+    }
+
+    @Override
+    public AnyType save(final AnyType anyType) {
+        return entityManager.merge(anyType);
+    }
+
+    @Override
+    public void delete(final String key) {
+        AnyType anyType = find(key);
+        if (anyType == null) {
+            return;
+        }
+
+        entityManager.remove(anyType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
deleted file mode 100644
index 2b33178..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
+++ /dev/null
@@ -1,107 +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.dao;
-
-import java.util.Collections;
-import java.util.List;
-import javax.persistence.Query;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttrTemplate;
-import org.springframework.stereotype.Repository;
-import org.springframework.util.ReflectionUtils;
-
-@Repository
-public class JPAAttrTemplateDAO<S extends Schema>
-        extends AbstractDAO<AttrTemplate<S>, Long> implements AttrTemplateDAO<S> {
-
-    private <T extends AttrTemplate<S>> Class<? extends AbstractAttrTemplate<? extends Schema>> getJPAEntityReference(
-            final Class<T> reference) {
-
-        return MPlainAttrTemplate.class.isAssignableFrom(reference)
-                ? JPAMPlainAttrTemplate.class
-                : MDerAttrTemplate.class.isAssignableFrom(reference)
-                        ? JPAMDerAttrTemplate.class
-                        : MVirAttrTemplate.class.isAssignableFrom(reference)
-                                ? JPAMVirAttrTemplate.class
-                                : GPlainAttrTemplate.class.isAssignableFrom(reference)
-                                        ? JPAGPlainAttrTemplate.class
-                                        : GDerAttrTemplate.class.isAssignableFrom(reference)
-                                                ? JPAGDerAttrTemplate.class
-                                                : GVirAttrTemplate.class.isAssignableFrom(reference)
-                                                        ? JPAGVirAttrTemplate.class
-                                                        : null;
-    }
-
-    @Override
-    public <T extends AttrTemplate<S>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T extends AttrTemplate<S>> List<Number> findBySchemaName(
-            final String schemaName, final Class<T> reference) {
-
-        Query query = null;
-        try {
-            query = entityManager.createNativeQuery("SELECT id FROM "
-                    + ReflectionUtils.findField(getJPAEntityReference(reference), "TABLE").get(null).toString()
-                    + " WHERE schema_name=?1");
-            query.setParameter(1, schemaName);
-        } catch (Exception e) {
-            LOG.error("Unexpected exception", e);
-        }
-
-        return query == null ? Collections.<Number>emptyList() : query.getResultList();
-    }
-
-    @Override
-    public <T extends AttrTemplate<S>> void delete(final Long key, final Class<T> reference) {
-        T attrTemplate = find(key, reference);
-        if (attrTemplate == null) {
-            return;
-        }
-
-        delete(attrTemplate);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T extends AttrTemplate<S>> void delete(final T attrTemplate) {
-        if (attrTemplate.getOwner() != null) {
-            attrTemplate.getOwner().getAttrTemplates(attrTemplate.getClass()).remove(attrTemplate);
-        }
-
-        entityManager.remove(attrTemplate);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
index 48e9f5e..7045a1a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -18,15 +18,14 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.Conf;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -41,9 +40,6 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
     @Autowired
     private PlainAttrDAO attrDAO;
 
-    @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
-
     @Override
     public Conf get() {
         Conf instance = entityManager.find(JPAConf.class, 1L);
@@ -68,10 +64,19 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
     public CPlainAttr find(final String key, final String defaultValue) {
         CPlainAttr result = find(key);
         if (result == null) {
-            result = new JPACPlainAttr();
-            result.setSchema(schemaDAO.find(key, CPlainSchema.class));
-
-            result.addValue(defaultValue, attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+            JPACPlainAttr newAttr = new JPACPlainAttr();
+            newAttr.setSchema(schemaDAO.find(key));
+
+            JPACPlainAttrValue attrValue;
+            if (newAttr.getSchema().isUniqueConstraint()) {
+                attrValue = new JPACPlainAttrValue();
+                ((PlainAttrUniqueValue) attrValue).setSchema(newAttr.getSchema());
+            } else {
+                attrValue = new JPACPlainAttrValue();
+            }
+            newAttr.add(defaultValue, attrValue);
+
+            result = newAttr;
         }
 
         return result;
@@ -85,11 +90,11 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         if (old != null && (!attr.getSchema().isUniqueConstraint()
                 || (!attr.getUniqueValue().getStringValue().equals(old.getUniqueValue().getStringValue())))) {
 
-            instance.removePlainAttr(old);
+            instance.remove(old);
             attrDAO.delete(old.getKey(), CPlainAttr.class);
         }
 
-        instance.addPlainAttr(attr);
+        instance.add(attr);
         attr.setOwner(instance);
 
         return entityManager.merge(instance);
@@ -100,7 +105,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         Conf instance = get();
         CPlainAttr attr = instance.getPlainAttr(key);
         if (attr != null) {
-            instance.removePlainAttr(attr);
+            instance.remove(attr);
             instance = entityManager.merge(instance);
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
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 e148b04..453c363 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
@@ -27,7 +27,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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
index ff32fb8..2162898 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
@@ -21,51 +21,51 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADerAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
 import org.springframework.stereotype.Repository;
 
 @Repository
-public class JPADerAttrDAO extends AbstractDAO<DerAttr, Long> implements DerAttrDAO {
+public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerAttrDAO {
 
-    public <T extends DerAttr> Class<? extends AbstractDerAttr> getJPAEntityReference(
+    public <T extends DerAttr<?>> Class<? extends AbstractDerAttr<?>> getJPAEntityReference(
             final Class<T> reference) {
 
         return GDerAttr.class.isAssignableFrom(reference)
                 ? JPAGDerAttr.class
-                : MDerAttr.class.isAssignableFrom(reference)
-                        ? JPAMDerAttr.class
+                : ADerAttr.class.isAssignableFrom(reference)
+                        ? JPAADerAttr.class
                         : UDerAttr.class.isAssignableFrom(reference)
                                 ? JPAUDerAttr.class
                                 : null;
     }
 
     @Override
-    public <T extends DerAttr> T find(final Long key, final Class<T> reference) {
+    public <T extends DerAttr<?>> T find(final Long key, final Class<T> reference) {
         return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
     }
 
     @Override
-    public <T extends DerAttr> List<T> findAll(final Class<T> reference) {
+    public <T extends DerAttr<?>> List<T> findAll(final Class<T> reference) {
         TypedQuery<T> query = entityManager.createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
-    public <T extends DerAttr> T save(final T derAttr) {
+    public <T extends DerAttr<?>> T save(final T derAttr) {
         return entityManager.merge(derAttr);
     }
 
     @Override
-    public <T extends DerAttr> void delete(final Long key, final Class<T> reference) {
+    public <T extends DerAttr<?>> void delete(final Long key, final Class<T> reference) {
         T derAttr = find(key, reference);
         if (derAttr == null) {
             return;
@@ -76,9 +76,9 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr, Long> implements DerAttr
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T extends DerAttr> void delete(final T derAttr) {
+    public <T extends DerAttr<?>> void delete(final T derAttr) {
         if (derAttr.getOwner() != null) {
-            ((Attributable<?, T, ?>) derAttr.getOwner()).removeDerAttr(derAttr);
+            ((Any<?, T, ?>) derAttr.getOwner()).remove(derAttr);
         }
 
         entityManager.remove(derAttr);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index be0ec94..c3c10bf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -20,25 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerSchema;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPADerSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -49,44 +40,25 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
     private DerAttrDAO derAttrDAO;
 
     @Autowired
-    private AttrTemplateDAO<DerSchema> attrTemplateDAO;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
-    private <T extends DerSchema> Class<? extends AbstractDerSchema> getJPAEntityReference(final Class<T> reference) {
-        return GDerSchema.class.isAssignableFrom(reference)
-                ? JPAGDerSchema.class
-                : MDerSchema.class.isAssignableFrom(reference)
-                        ? JPAMDerSchema.class
-                        : UDerSchema.class.isAssignableFrom(reference)
-                                ? JPAUDerSchema.class
-                                : null;
-    }
-
     @Override
-    public <T extends DerSchema> T find(final String key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+    public DerSchema find(final String key) {
+        return entityManager.find(JPADerSchema.class, key);
     }
 
     @Override
-    public <T extends DerSchema> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
-                "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+    public List<DerSchema> findAll() {
+        TypedQuery<DerSchema> query = entityManager.createQuery(
+                "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
         return query.getResultList();
     }
 
     @Override
-    public <T extends DerAttr> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
+    public <T extends DerAttr<?>> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
         final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
-                append(" e WHERE e.");
-        if (UDerAttr.class.isAssignableFrom(reference)) {
-            queryString.append("derSchema");
-        } else {
-            queryString.append("template.schema");
-        }
-        queryString.append("=:schema");
+                append(" e WHERE e.schema=:schema");
 
         TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
@@ -95,42 +67,28 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
     }
 
     @Override
-    public <T extends DerSchema> T save(final T derSchema) {
+    public DerSchema save(final DerSchema derSchema) {
         return entityManager.merge(derSchema);
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public void delete(final String key, final AttributableUtils attributableUtil) {
-        final DerSchema schema = find(key, attributableUtil.derSchemaClass());
+    public void delete(final String key) {
+        final DerSchema schema = find(key);
         if (schema == null) {
             return;
         }
 
-        CollectionUtils.forAllDo(findAttrs(schema, attributableUtil.derAttrClass()), new Closure<DerAttr>() {
+        AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory();
+        for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
 
-            @Override
-            public void execute(final DerAttr input) {
-                derAttrDAO.delete(input.getKey(), attributableUtil.derAttrClass());
+            for (DerAttr<?> attr : findAttrs(schema, anyUtils.derAttrClass())) {
+                derAttrDAO.delete(attr.getKey(), anyUtils.derAttrClass());
             }
 
-        });
-
-        if (attributableUtil.getType() != AttributableType.USER) {
-            CollectionUtils.forAllDo(attrTemplateDAO.
-                    findBySchemaName(schema.getKey(), attributableUtil.derAttrTemplateClass()).iterator(),
-                    new Closure<Number>() {
-
-                        @Override
-                        public void execute(final Number input) {
-                            attrTemplateDAO.delete(input.longValue(), attributableUtil.derAttrTemplateClass());
-                        }
-
-                    });
+            resourceDAO.deleteMapping(key, anyUtils.derIntMappingType());
         }
 
-        resourceDAO.deleteMapping(key, attributableUtil.derIntMappingType(), UMappingItem.class);
-
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
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 70f00f7..b13a8bd 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
@@ -25,6 +25,7 @@ import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
@@ -32,17 +33,17 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 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.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+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.Policy;
+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.user.UMappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
+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.provisioning.api.ConnectorRegistry;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -55,6 +56,9 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     private TaskDAO taskDAO;
 
     @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -66,6 +70,9 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     @Autowired
     private ConnectorRegistry connRegistry;
 
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
     @Override
     public ExternalResource find(final String name) {
         return entityManager.find(JPAExternalResource.class, name);
@@ -146,33 +153,25 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T extends MappingItem> void deleteMapping(
-            final String intAttrName, final IntMappingType intMappingType, final Class<T> reference) {
-
+    public void deleteMapping(final String intAttrName, final IntMappingType intMappingType) {
         if (IntMappingType.getEmbedded().contains(intMappingType)) {
             return;
         }
 
-        Class<? extends AbstractMappingItem> jpaRef = reference.equals(UMappingItem.class)
-                ? JPAUMappingItem.class
-                : JPAGMappingItem.class;
-
-        TypedQuery<T> query = entityManager.createQuery("SELECT m FROM " + jpaRef.getSimpleName()
-                + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", reference);
+        TypedQuery<MappingItem> query = entityManager.createQuery(
+                "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
+                + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", MappingItem.class);
         query.setParameter("intAttrName", intAttrName);
         query.setParameter("intMappingType", intMappingType);
 
-        Set<Long> itemIds = new HashSet<>();
-        for (T item : query.getResultList()) {
-            itemIds.add(item.getKey());
+        Set<Long> itemKeys = new HashSet<>();
+        for (MappingItem item : query.getResultList()) {
+            itemKeys.add(item.getKey());
         }
-        Class<?> mappingRef = null;
-        for (Long itemId : itemIds) {
-            T item = (T) entityManager.find(jpaRef, itemId);
+        for (Long itemKey : itemKeys) {
+            MappingItem item = entityManager.find(JPAMappingItem.class, itemKey);
             if (item != null) {
-                mappingRef = item.getMapping().getClass();
-
-                ((Mapping<T>) item.getMapping()).removeItem(item);
+                item.getMapping().remove(item);
                 item.setMapping(null);
 
                 entityManager.remove(item);
@@ -180,10 +179,8 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         }
 
         // Make empty query cache for *MappingItem and related *Mapping
-        entityManager.getEntityManagerFactory().getCache().evict(jpaRef);
-        if (mappingRef != null) {
-            entityManager.getEntityManagerFactory().getCache().evict(mappingRef);
-        }
+        entityManager.getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
+        entityManager.getEntityManagerFactory().getCache().evict(JPAMapping.class);
     }
 
     @Override
@@ -197,11 +194,14 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         taskDAO.deleteAll(resource, TaskType.SYNCHRONIZATION);
         taskDAO.deleteAll(resource, TaskType.PUSH);
 
+        for (AnyObject anyObject : anyObjectDAO.findByResource(resource)) {
+            anyObject.remove(resource);
+        }
         for (User user : userDAO.findByResource(resource)) {
-            user.removeResource(resource);
+            user.remove(resource);
         }
         for (Group group : groupDAO.findByResource(resource)) {
-            group.removeResource(resource);
+            group.remove(resource);
         }
         for (AccountPolicy policy : policyDAO.findByResource(resource)) {
             policy.removeResource(resource);
@@ -214,21 +214,13 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
         }
         resource.setConnector(null);
 
-        if (resource.getUmapping() != null) {
-            for (MappingItem item : resource.getUmapping().getItems()) {
-                item.setMapping(null);
-            }
-            resource.getUmapping().getItems().clear();
-            resource.getUmapping().setResource(null);
-            resource.setUmapping(null);
-        }
-        if (resource.getGmapping() != null) {
-            for (MappingItem item : resource.getGmapping().getItems()) {
+        for (Provision provision : resource.getProvisions()) {
+            for (MappingItem item : provision.getMapping().getItems()) {
                 item.setMapping(null);
             }
-            resource.getGmapping().getItems().clear();
-            resource.getGmapping().setResource(null);
-            resource.setGmapping(null);
+            provision.getMapping().getItems().clear();
+            provision.setMapping(null);
+            provision.setResource(null);
         }
 
         entityManager.remove(resource);


[05/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
index b3a73df..b854921 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
@@ -22,20 +22,21 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeSyncResultHandler;
@@ -51,19 +52,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     protected SyncUtils syncUtilities;
 
     @Autowired
-    protected AttributableTransformer attrTransformer;
+    protected AnyTransformer anyTransformer;
 
-    protected abstract String getName(AbstractSubjectTO subjectTO);
+    protected abstract String getName(AnyTO anyTO);
 
-    protected abstract AbstractSubjectMod getSubjectMod(AbstractSubjectTO subjectTO, SyncDelta delta);
+    protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningResult result);
 
-    protected abstract AbstractSubjectTO doCreate(
-            AbstractSubjectTO subjectTO, SyncDelta delta, ProvisioningResult result);
+    protected abstract AnyTO doLink(AnyTO before, ProvisioningResult result, boolean unlink);
 
-    protected abstract AbstractSubjectTO doLink(AbstractSubjectTO before, ProvisioningResult result, boolean unlink);
-
-    protected abstract AbstractSubjectTO doUpdate(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
-            SyncDelta delta, ProvisioningResult result);
+    protected abstract AnyTO doUpdate(AnyTO before, AnyMod anyMod, SyncDelta delta, ProvisioningResult result);
 
     protected abstract void doDeprovision(Long key, boolean unlink);
 
@@ -71,13 +68,21 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     @Override
     public boolean handle(final SyncDelta delta) {
+        Provision provision = null;
         try {
-            doHandle(delta);
+            provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass());
+            if (provision == null) {
+                throw new JobExecutionException("No provision found on " + profile.getTask().getResource() + " for "
+                        + delta.getObject().getObjectClass());
+            }
+
+            doHandle(delta, provision);
             return true;
         } catch (IgnoreProvisionException e) {
             ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(getAttributableUtils().getType());
+            result.setAnyType(provision == null
+                    ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.IGNORE);
             result.setKey(0L);
             result.setName(delta.getObject().getName().getNameValue());
@@ -91,7 +96,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected List<ProvisioningResult> assign(final SyncDelta delta, final AttributableUtils attrUtils)
+    protected List<ProvisioningResult> assign(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformCreate()) {
@@ -99,18 +105,17 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        final AbstractSubjectTO subjectTO =
-                connObjectUtils.getSubjectTO(delta.getObject(), profile.getTask(), attrUtils);
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
 
-        subjectTO.getResources().add(profile.getTask().getResource().getKey());
+        anyTO.getResources().add(profile.getTask().getResource().getKey());
 
         final ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
 
         // Attributable transformation (if configured)
-        AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+        AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
         result.setName(getName(transformed));
@@ -123,13 +128,14 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, transformed);
             }
 
-            create(transformed, actionedDelta, attrUtils, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+            create(transformed, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
         }
 
         return Collections.singletonList(result);
     }
 
-    protected List<ProvisioningResult> provision(final SyncDelta delta, final AttributableUtils attrUtils)
+    protected List<ProvisioningResult> provision(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformCreate()) {
@@ -137,16 +143,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        final AbstractSubjectTO subjectTO =
-                connObjectUtils.getSubjectTO(delta.getObject(), profile.getTask(), attrUtils);
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
 
         // Attributable transformation (if configured)
-        AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+        AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
         final ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
 
         result.setName(getName(transformed));
@@ -159,16 +164,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, transformed);
             }
 
-            create(transformed, actionedDelta, attrUtils, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+            create(transformed, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
         }
 
         return Collections.<ProvisioningResult>singletonList(result);
     }
 
     private void create(
-            final AbstractSubjectTO subjectTO,
+            final AnyTO anyTO,
             final SyncDelta delta,
-            final AttributableUtils attrUtils,
             final String operation,
             final ProvisioningResult result)
             throws JobExecutionException {
@@ -177,7 +181,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         Result resultStatus;
 
         try {
-            AbstractSubjectTO actual = doCreate(subjectTO, delta, result);
+            AnyTO actual = doCreate(anyTO, delta, result);
             result.setName(getName(actual));
             output = actual;
             resultStatus = Result.SUCCESS;
@@ -190,7 +194,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         } catch (PropagationException e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.
-            LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+            LOG.error("Could not propagate {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
 
@@ -200,7 +204,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         } catch (Exception e) {
             result.setStatus(ProvisioningResult.Status.FAILURE);
             result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-            LOG.error("Could not create {} {} ", attrUtils.getType(), delta.getUid().getUidValue(), e);
+            LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
 
@@ -212,32 +216,32 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         audit(operation, resultStatus, null, output, delta);
     }
 
-    protected List<ProvisioningResult> update(final SyncDelta delta, final List<Long> subjects,
-            final AttributableUtils attrUtils) throws JobExecutionException {
+    protected List<ProvisioningResult> update(final SyncDelta delta, final List<Long> anys,
+            final Provision provision) throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("SyncTask not configured for update");
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         List<ProvisioningResult> results = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
-        for (Long key : subjects) {
+        for (Long key : anys) {
             LOG.debug("About to update {}", key);
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.UPDATE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(key);
 
-            AbstractSubjectTO before = getSubjectTO(key);
+            AnyTO before = getAnyTO(key);
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), key));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
             } else {
                 result.setName(getName(before));
             }
@@ -250,17 +254,23 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     output = null;
                 } else {
                     try {
-                        AbstractSubjectMod subjectMod = getSubjectMod(before, workingDelta);
+                        AnyMod anyMod = connObjectUtils.getAnyMod(
+                                before.getKey(),
+                                workingDelta.getObject(),
+                                before,
+                                profile.getTask(),
+                                provision,
+                                getAnyUtils());
 
                         // Attribute value transformation (if configured)
-                        AbstractSubjectMod actual = attrTransformer.transform(subjectMod);
+                        AnyMod actual = anyTransformer.transform(anyMod);
                         LOG.debug("Transformed: {}", actual);
 
                         for (SyncActions action : profile.getActions()) {
-                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, subjectMod);
+                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyMod);
                         }
 
-                        final AbstractSubjectTO updated = doUpdate(before, subjectMod, workingDelta, result);
+                        final AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), workingDelta, updated, result);
@@ -269,14 +279,14 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         output = updated;
                         resultStatus = Result.SUCCESS;
                         result.setName(getName(updated));
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), key);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
                         LOG.error("Could not propagate {} {}",
-                                attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -287,7 +297,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
                         LOG.error("Could not update {} {}",
-                                attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -305,8 +315,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     protected List<ProvisioningResult> deprovision(
             final SyncDelta delta,
-            final List<Long> subjects,
-            final AttributableUtils attrUtils,
+            final List<Long> anys,
+            final Provision provision,
             final boolean unlink)
             throws JobExecutionException {
 
@@ -315,11 +325,11 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : subjects) {
+        for (Long id : anys) {
             LOG.debug("About to unassign resource {}", id);
 
             Object output;
@@ -327,15 +337,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
             final ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.DELETE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AbstractSubjectTO before = getSubjectTO(id);
+            final AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
             }
 
             if (!profile.isDryRun()) {
@@ -357,20 +367,21 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         }
 
                         doDeprovision(id, unlink);
-                        output = getSubjectTO(id);
+                        output = getAnyTO(id);
 
                         for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
-                        LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -380,7 +391,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -401,8 +413,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     protected List<ProvisioningResult> link(
             final SyncDelta delta,
-            final List<Long> subjects,
-            final AttributableUtils attrUtils,
+            final List<Long> anys,
+            final Provision provision,
             final boolean unlink)
             throws JobExecutionException {
 
@@ -411,27 +423,27 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : subjects) {
+        for (Long id : anys) {
             LOG.debug("About to unassign resource {}", id);
 
             Object output;
             Result resultStatus;
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AbstractSubjectTO before = getSubjectTO(id);
+            final AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
             }
 
             if (!profile.isDryRun()) {
@@ -455,17 +467,18 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         output = doLink(before, result, unlink);
 
                         for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
-                        LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -475,7 +488,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -494,7 +508,9 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     }
 
     protected List<ProvisioningResult> delete(
-            final SyncDelta delta, final List<Long> subjects, final AttributableUtils attrUtils)
+            final SyncDelta delta,
+            final List<Long> anys,
+            final Provision provision)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformDelete()) {
@@ -502,25 +518,25 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to delete {}", subjects);
+        LOG.debug("About to delete {}", anys);
 
         List<ProvisioningResult> delResults = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
-        for (Long id : subjects) {
+        for (Long id : anys) {
             Object output;
             Result resultStatus = Result.FAILURE;
 
-            AbstractSubjectTO before = null;
+            AnyTO before = null;
             final ProvisioningResult result = new ProvisioningResult();
 
             try {
-                before = getSubjectTO(id);
+                before = getAnyTO(id);
 
                 result.setKey(id);
                 result.setName(getName(before));
                 result.setOperation(ResourceOperation.DELETE);
-                result.setSubjectType(attrUtils.getType());
+                result.setAnyType(provision.getAnyType().getKey());
                 result.setStatus(ProvisioningResult.Status.SUCCESS);
 
                 if (!profile.isDryRun()) {
@@ -541,7 +557,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not delete {} {}", attrUtils.getType(), id, e);
+                        LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), id, e);
                         output = e;
 
                         for (SyncActions action : profile.getActions()) {
@@ -554,21 +570,24 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
                 delResults.add(result);
             } catch (NotFoundException e) {
-                LOG.error("Could not find {} {}", attrUtils.getType(), id, e);
+                LOG.error("Could not find {} {}", provision.getAnyType().getKey(), id, e);
             } catch (UnauthorizedException e) {
-                LOG.error("Not allowed to read {} {}", attrUtils.getType(), id, e);
+                LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), id, e);
             } catch (Exception e) {
-                LOG.error("Could not delete {} {}", attrUtils.getType(), id, e);
+                LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), id, e);
             }
         }
 
         return delResults;
     }
 
-    private List<ProvisioningResult> ignore(final SyncDelta delta, final AttributableUtils attrUtils,
-            final boolean matching) throws JobExecutionException {
+    private List<ProvisioningResult> ignore(
+            final SyncDelta delta,
+            final Provision provision,
+            final boolean matching)
+            throws JobExecutionException {
 
-        LOG.debug("Subject to ignore {}", delta.getObject().getUid().getUidValue());
+        LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
 
         final List<ProvisioningResult> ignoreResults = new ArrayList<>();
         final ProvisioningResult result = new ProvisioningResult();
@@ -576,7 +595,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         result.setKey(null);
         result.setName(delta.getObject().getUid().getUidValue());
         result.setOperation(ResourceOperation.NONE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
         ignoreResults.add(result);
 
@@ -590,89 +609,92 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     }
 
     /**
-     * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on user(s)/group(s).
+     * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on any object(s).
      *
      * @param delta returned by the underlying profile.getConnector()
+     * @param provision provisioning info
      * @throws JobExecutionException in case of synchronization failure.
      */
-    protected void doHandle(final SyncDelta delta)
+    protected void doHandle(final SyncDelta delta, final Provision provision)
             throws JobExecutionException {
 
-        final AttributableUtils attrUtils = getAttributableUtils();
+        AnyUtils anyUtils = getAnyUtils();
 
         LOG.debug("Process {} for {} as {}",
                 delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
 
-        final String uid = delta.getPreviousUid() == null
+        String uid = delta.getPreviousUid() == null
                 ? delta.getUid().getUidValue()
                 : delta.getPreviousUid().getUidValue();
 
         try {
-            List<Long> subjectKeys = syncUtilities.findExisting(
-                    uid, delta.getObject(), profile.getTask().getResource(), attrUtils);
+            List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils);
 
-            if (subjectKeys.size() > 1) {
+            if (anyKeys.size() > 1) {
                 switch (profile.getResAct()) {
                     case IGNORE:
-                        throw new IllegalStateException("More than one match " + subjectKeys);
+                        throw new IllegalStateException("More than one match " + anyKeys);
 
                     case FIRSTMATCH:
-                        subjectKeys = subjectKeys.subList(0, 1);
+                        anyKeys = anyKeys.subList(0, 1);
                         break;
 
                     case LASTMATCH:
-                        subjectKeys = subjectKeys.subList(subjectKeys.size() - 1, subjectKeys.size());
+                        anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
                         break;
 
                     default:
-                    // keep subjectIds as is
+                    // keep anyIds as is
                 }
             }
 
             if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
-                if (subjectKeys.isEmpty()) {
+                if (anyKeys.isEmpty()) {
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
-                            profile.getResults().addAll(assign(delta, attrUtils));
+                            profile.getResults().addAll(assign(delta, provision, anyUtils));
                             break;
+
                         case PROVISION:
-                            profile.getResults().addAll(provision(delta, attrUtils));
+                            profile.getResults().addAll(provision(delta, provision, anyUtils));
                             break;
+
                         case IGNORE:
-                            profile.getResults().addAll(ignore(delta, attrUtils, false));
+                            profile.getResults().addAll(ignore(delta, provision, false));
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
-                            profile.getResults().addAll(update(delta, subjectKeys, attrUtils));
+                            profile.getResults().addAll(update(delta, anyKeys, provision));
                             break;
                         case DEPROVISION:
-                            profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtils, false));
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
                             break;
                         case UNASSIGN:
-                            profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtils, true));
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
                             break;
                         case LINK:
-                            profile.getResults().addAll(link(delta, subjectKeys, attrUtils, false));
+                            profile.getResults().addAll(link(delta, anyKeys, provision, false));
                             break;
                         case UNLINK:
-                            profile.getResults().addAll(link(delta, subjectKeys, attrUtils, true));
+                            profile.getResults().addAll(link(delta, anyKeys, provision, true));
                             break;
                         case IGNORE:
-                            profile.getResults().addAll(ignore(delta, attrUtils, true));
+                            profile.getResults().addAll(ignore(delta, provision, true));
                             break;
                         default:
                         // do nothing
                     }
                 }
             } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
-                if (subjectKeys.isEmpty()) {
+                if (anyKeys.isEmpty()) {
                     LOG.debug("No match found for deletion");
                 } else {
-                    profile.getResults().addAll(delete(delta, subjectKeys, attrUtils));
+                    profile.getResults().addAll(delete(delta, anyKeys, provision));
                 }
             }
         } catch (IllegalStateException | IllegalArgumentException e) {
@@ -688,7 +710,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             final Object... input) {
 
         notificationManager.createTasks(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAttributableUtils().getType().name().toLowerCase(),
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
                 profile.getTask().getResource().getKey(),
                 event,
                 result,
@@ -697,7 +719,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 input);
 
         auditManager.audit(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAttributableUtils().getType().name().toLowerCase(),
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
                 profile.getTask().getResource().getKey(),
                 event,
                 result,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
index 28c3885..fccecc4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
@@ -18,10 +18,9 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
@@ -34,8 +33,13 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
 import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.misc.ConnObjectUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.slf4j.Logger;
@@ -51,6 +55,9 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
 
     @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     protected UserDAO userDAO;
 
     @Autowired
@@ -86,6 +93,8 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     @Autowired
     protected PropagationTaskExecutor taskExecutor;
 
+    protected AnyObjectWorkflowAdapter awfAdapter;
+
     /**
      * User workflow adapter.
      */
@@ -99,28 +108,34 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     protected GroupWorkflowAdapter gwfAdapter;
 
     @Autowired
+    protected AnyObjectDataBinder anyObjectDataBinder;
+
+    @Autowired
     protected UserDataBinder userDataBinder;
 
     @Autowired
     protected GroupDataBinder groupDataBinder;
 
     @Autowired
+    protected AnyObjectProvisioningManager anyObjectProvisioningManager;
+
+    @Autowired
     protected UserProvisioningManager userProvisioningManager;
 
     @Autowired
     protected GroupProvisioningManager groupProvisioningManager;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
     /**
      * Sync profile.
      */
     protected ProvisioningProfile<T, A> profile;
 
-    protected abstract AttributableUtils getAttributableUtils();
+    protected abstract AnyUtils getAnyUtils();
 
-    protected abstract AbstractSubjectTO getSubjectTO(long key);
+    protected abstract AnyTO getAnyTO(long key);
 
     @Override
     public void setProfile(final ProvisioningProfile<T, A> profile) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
new file mode 100644
index 0000000..fcfb537
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+    }
+
+    @Override
+    protected Any<?, ?, ?> deprovision(final Any<?, ?, ?> sbj) {
+        AnyObjectTO before = anyObjectDataBinder.getAnyObjectTO(AnyObject.class.cast(sbj));
+
+        List<String> noPropResources = new ArrayList<>(before.getResources());
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(before.getKey(), noPropResources));
+
+        return anyObjectDAO.authFind(before.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> provision(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        AnyObjectTO before = anyObjectDataBinder.getAnyObjectTO(AnyObject.class.cast(sbj));
+
+        List<String> noPropResources = new ArrayList<>(before.getResources());
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getAnyObjectCreateTasks(
+                before.getKey(),
+                Collections.unmodifiableCollection(before.getVirAttrs()),
+                propByRes,
+                noPropResources));
+
+        return anyObjectDAO.authFind(before.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> link(final Any<?, ?, ?> sbj, final Boolean unlink) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+
+        if (unlink) {
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        } else {
+            anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        }
+
+        awfAdapter.update(anyObjectMod);
+
+        return anyObjectDAO.authFind(sbj.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> unassign(final Any<?, ?, ?> sbj) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+        anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        awfAdapter.update(anyObjectMod);
+        return deprovision(sbj);
+    }
+
+    @Override
+    protected Any<?, ?, ?> assign(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+        anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        awfAdapter.update(anyObjectMod);
+        return provision(sbj, enabled);
+    }
+
+    @Override
+    protected String getName(final Any<?, ?, ?> subject) {
+        return StringUtils.EMPTY;
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        try {
+            return anyObjectDataBinder.getAnyObjectTO(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving user {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected Any<?, ?, ?> getAny(final long key) {
+        try {
+            return anyObjectDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving anyObject {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+        ConnectorObject obj = null;
+        try {
+            Uid uid = new Uid(connObjectKey);
+
+            obj = profile.getConnector().getObject(
+                    objectClass,
+                    uid,
+                    profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+        } catch (TimeoutException toe) {
+            LOG.debug("Request timeout", toe);
+            throw toe;
+        } catch (RuntimeException ignore) {
+            LOG.debug("While resolving {}", connObjectKey, ignore);
+        }
+
+        return obj;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
new file mode 100644
index 0000000..2b4b667
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler implements AnyObjectSyncResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+    }
+
+    @Override
+    protected String getName(final AnyTO anyTO) {
+        return StringUtils.EMPTY;
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        try {
+            return anyObjectDataBinder.getAnyObjectTO(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving anyObject {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
+        AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+        Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+                anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()));
+
+        anyObjectTO = anyObjectDataBinder.getAnyObjectTO(created.getKey());
+
+        result.setKey(created.getKey());
+        result.setName(getName(anyTO));
+
+        return anyObjectTO;
+    }
+
+    @Override
+    protected AnyTO doLink(
+            final AnyTO before,
+            final ProvisioningResult result,
+            final boolean unlink) {
+
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(before.getKey());
+
+        if (unlink) {
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        } else {
+            anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        }
+
+        return anyObjectDataBinder.getAnyObjectTO(awfAdapter.update(anyObjectMod).getResult());
+    }
+
+    @Override
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyMod anyMod,
+            final SyncDelta delta,
+            final ProvisioningResult result) {
+
+        AnyObjectMod anyObjectMod = AnyObjectMod.class.cast(anyMod);
+
+        Map.Entry<Long, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(anyObjectMod);
+
+        AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
+        result.setName(getName(after));
+        return after;
+    }
+
+    @Override
+    protected void doDeprovision(final Long key, final boolean unlink) {
+        taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(
+                key, profile.getTask().getResource().getKey()));
+
+        if (unlink) {
+            AnyObjectMod anyObjectMod = new AnyObjectMod();
+            anyObjectMod.setKey(key);
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        }
+    }
+
+    @Override
+    protected void doDelete(final Long key) {
+        try {
+            taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(
+                    key, profile.getTask().getResource().getKey()));
+        } catch (Exception e) {
+            // A propagation failure doesn't imply a synchronization failure.
+            // The propagation exception status will be reported into the propagation task execution.
+            LOG.error("Could not propagate anyObject " + key, e);
+        }
+
+        anyObjectProvisioningManager.delete(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
index 2b3ca02..5615876 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
@@ -20,9 +20,9 @@ package org.apache.syncope.core.provisioning.java.sync;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -59,13 +59,13 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+    public <T extends AnyTO> SyncDelta beforeProvision(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject) throws JobExecutionException {
+            final T any) throws JobExecutionException {
 
-        if (subject instanceof UserTO) {
-            String password = ((UserTO) subject).getPassword();
+        if (any instanceof UserTO) {
+            String password = ((UserTO) any).getPassword();
             parseEncodedPassword(password, profile.getConnector());
         }
 
@@ -74,14 +74,14 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
-            final K subjectMod) throws JobExecutionException {
+            final T any,
+            final K anyMod) throws JobExecutionException {
 
-        if (subjectMod instanceof UserMod) {
-            String modPassword = ((UserMod) subjectMod).getPassword();
+        if (anyMod instanceof UserMod) {
+            String modPassword = ((UserMod) anyMod).getPassword();
             parseEncodedPassword(modPassword, profile.getConnector());
         }
 
@@ -123,14 +123,14 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> void after(
+    public <T extends AnyTO> void after(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
+            final T any,
             final ProvisioningResult result) throws JobExecutionException {
 
-        if (subject instanceof UserTO && encodedPassword != null && cipher != null) {
-            User syncopeUser = userDAO.find(subject.getKey());
+        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+            User syncopeUser = userDAO.find(any.getKey());
             if (syncopeUser != null) {
                 syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
index fa5f843..14da889 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
@@ -34,58 +34,58 @@ public abstract class DefaultPushActions implements PushActions {
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeAssign(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeAssign(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeProvision(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeProvision(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeLink(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeLink(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeUnassign(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeUnassign(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeDeprovision(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeDeprovision(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeUnlink(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeUnlink(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> void onError(
-            final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result,
+    public <T extends Any<?, ?, ?>> void onError(
+            final ProvisioningProfile<?, ?> profile, final T any, final ProvisioningResult result,
             final Exception error) throws JobExecutionException {
 
         // do nothing
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> void after(
-            final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result)
+    public <T extends Any<?, ?, ?>> void after(
+            final ProvisioningProfile<?, ?> profile, final T any, final ProvisioningResult result)
             throws JobExecutionException {
 
         // do nothing

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
index 8f3432a..29d7662 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
@@ -36,66 +36,66 @@ public abstract class DefaultSyncActions implements SyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
-            final K subjectMod) throws JobExecutionException {
+            final T any,
+            final K anyMod) throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeDelete(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeDelete(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeAssign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeAssign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeLink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeLink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeUnassign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeUnassign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeDeprovision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeDeprovision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeUnlink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeUnlink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
@@ -108,8 +108,8 @@ public abstract class DefaultSyncActions implements SyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO> void after(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject,
+    public <T extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any,
             final ProvisioningResult result)
             throws JobExecutionException {
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
index c38e5d6..38ae900 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
@@ -22,16 +22,15 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -41,30 +40,30 @@ import org.identityconnectors.framework.common.objects.Uid;
 public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.GROUP);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
     }
 
     @Override
-    protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
-        final GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
+    protected Any<?, ?, ?> deprovision(final Any<?, ?, ?> sbj) {
+        GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getGroupDeleteTasks(before.getKey(), noPropResources));
 
-        return groupDAO.authFetch(before.getKey());
+        return groupDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
+    protected Any<?, ?, ?> provision(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
-        final PropagationByResource propByRes = new PropagationByResource();
+        PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getGroupCreateTasks(
@@ -73,12 +72,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
                 propByRes,
                 noPropResources));
 
-        return groupDAO.authFetch(before.getKey());
+        return groupDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> link(final Any<?, ?, ?> sbj, final Boolean unlink) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
 
         if (unlink) {
@@ -89,12 +88,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
 
         gwfAdapter.update(groupMod);
 
-        return groupDAO.authFetch(sbj.getKey());
+        return groupDAO.authFind(sbj.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> unassign(final Any<?, ?, ?> sbj) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
         groupMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         gwfAdapter.update(groupMod);
@@ -102,8 +101,8 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> assign(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
         groupMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
         gwfAdapter.update(groupMod);
@@ -111,12 +110,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected String getName(final Subject<?, ?, ?> subject) {
+    protected String getName(final Any<?, ?, ?> subject) {
         return Group.class.cast(subject).getName();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return groupDataBinder.getGroupTO(key);
         } catch (Exception e) {
@@ -126,9 +125,9 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected Subject<?, ?, ?> getSubject(final long key) {
+    protected Any<?, ?, ?> getAny(final long key) {
         try {
-            return groupDAO.authFetch(key);
+            return groupDAO.authFind(key);
         } catch (Exception e) {
             LOG.warn("Error retrieving group {}", key, e);
             return null;
@@ -136,27 +135,22 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected ConnectorObject getRemoteObject(final String accountId) {
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
         ConnectorObject obj = null;
-
         try {
-            final Uid uid = new Uid(accountId);
+            Uid uid = new Uid(connObjectKey);
 
             obj = profile.getConnector().getObject(
-                    ObjectClass.GROUP,
+                    objectClass,
                     uid,
                     profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", accountId, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
-        return obj;
-    }
 
-    @Override
-    protected Mapping<?> getMapping() {
-        return profile.getTask().getResource().getGmapping();
+        return obj;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
index 1ce0357..f6218ce 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
@@ -22,15 +22,14 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
 import org.identityconnectors.framework.common.objects.SyncDelta;
@@ -45,17 +44,17 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.GROUP);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
     }
 
     @Override
-    protected String getName(final AbstractSubjectTO subjectTO) {
-        return GroupTO.class.cast(subjectTO).getName();
+    protected String getName(final AnyTO anyTO) {
+        return GroupTO.class.cast(anyTO).getName();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return groupDataBinder.getGroupTO(key);
         } catch (Exception e) {
@@ -65,20 +64,8 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AbstractSubjectMod getSubjectMod(final AbstractSubjectTO subjectTO, final SyncDelta delta) {
-        return connObjectUtils.getAttributableMod(
-                subjectTO.getKey(),
-                delta.getObject(),
-                subjectTO,
-                profile.getTask(),
-                attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @Override
-    protected AbstractSubjectTO doCreate(
-            final AbstractSubjectTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
-
-        GroupTO groupTO = GroupTO.class.cast(subjectTO);
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
+        GroupTO groupTO = GroupTO.class.cast(anyTO);
 
         Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(groupTO, groupOwnerMap,
                 Collections.singleton(profile.getTask().getResource().getKey()));
@@ -86,18 +73,18 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
         groupTO = groupDataBinder.getGroupTO(created.getKey());
 
         result.setKey(created.getKey());
-        result.setName(getName(subjectTO));
+        result.setName(getName(anyTO));
 
         return groupTO;
     }
 
     @Override
-    protected AbstractSubjectTO doLink(
-            final AbstractSubjectTO before,
+    protected AnyTO doLink(
+            final AnyTO before,
             final ProvisioningResult result,
             final boolean unlink) {
 
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(before.getKey());
 
         if (unlink) {
@@ -110,13 +97,13 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AbstractSubjectTO doUpdate(
-            final AbstractSubjectTO before,
-            final AbstractSubjectMod subjectMod,
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyMod anyMod,
             final SyncDelta delta,
             final ProvisioningResult result) {
 
-        GroupMod groupMod = GroupMod.class.cast(subjectMod);
+        GroupMod groupMod = GroupMod.class.cast(anyMod);
 
         Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupMod);
 
@@ -139,28 +126,26 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected void doDeprovision(final Long id, final boolean unlink) {
-        taskExecutor.execute(
-                propagationManager.getGroupDeleteTasks(id, profile.getTask().getResource().getKey()));
+    protected void doDeprovision(final Long key, final boolean unlink) {
+        taskExecutor.execute(propagationManager.getGroupDeleteTasks(key, profile.getTask().getResource().getKey()));
 
         if (unlink) {
-            final UserMod userMod = new UserMod();
-            userMod.setKey(id);
-            userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+            GroupMod groupMod = new GroupMod();
+            groupMod.setKey(key);
+            groupMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         }
     }
 
     @Override
-    protected void doDelete(final Long id) {
+    protected void doDelete(final Long key) {
         try {
-            taskExecutor.execute(
-                    propagationManager.getGroupDeleteTasks(id, profile.getTask().getResource().getKey()));
+            taskExecutor.execute(propagationManager.getGroupDeleteTasks(key, profile.getTask().getResource().getKey()));
         } catch (Exception e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.
-            LOG.error("Could not propagate user " + id, e);
+            LOG.error("Could not propagate group " + key, e);
         }
 
-        groupProvisioningManager.delete(id);
+        groupProvisioningManager.delete(key);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
index fc68ec0..fb2f9a4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
@@ -25,17 +25,14 @@ import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
@@ -48,6 +45,9 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.identityconnectors.framework.common.objects.Attribute;
@@ -70,6 +70,9 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipSyncActions.class);
 
     @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     protected GroupDAO groupDAO;
 
     @Autowired
@@ -88,7 +91,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     private AuditManager auditManager;
 
     @Autowired
-    private SyncUtils syncUtilities;
+    private SyncUtils syncUtils;
 
     protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
 
@@ -122,24 +125,24 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * {@inheritDoc}
      */
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta, final T subject, final K subjectMod) throws JobExecutionException {
+            final SyncDelta delta, final T any, final K anyMod) throws JobExecutionException {
 
-        if (subject instanceof GroupTO) {
+        if (any instanceof GroupTO) {
             // search for all users assigned to given group
-            Group group = groupDAO.find(subject.getKey());
+            Group group = groupDAO.find(any.getKey());
             if (group != null) {
-                List<Membership> membs = groupDAO.findMemberships(group);
+                List<UMembership> membs = groupDAO.findUMemberships(group);
                 // save memberships before group update takes place
                 membersBeforeGroupUpdate = new HashMap<>(membs.size());
-                for (Membership memb : membs) {
-                    membersBeforeGroupUpdate.put(memb.getUser().getKey(), memb.getKey());
+                for (UMembership memb : membs) {
+                    membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
                 }
             }
         }
 
-        return super.beforeUpdate(profile, delta, subject, subjectMod);
+        return super.beforeUpdate(profile, delta, any, anyMod);
     }
 
     /**
@@ -156,10 +159,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
             membersBeforeGroupUpdate.remove(userKey);
         } else {
             userMod.setKey(userKey);
-
-            MembershipMod membershipMod = new MembershipMod();
-            membershipMod.setGroup(groupTO.getKey());
-            userMod.getMembershipsToAdd().add(membershipMod);
+            userMod.getMembershipsToAdd().add(groupTO.getKey());
         }
 
         return userMod;
@@ -256,16 +256,16 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * @throws JobExecutionException if anything goes wrong
      */
     protected void synchronizeMemberships(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO) throws
-            JobExecutionException {
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
+            throws JobExecutionException {
 
-        final ProvisioningTask task = profile.getTask();
-        final ExternalResource resource = task.getResource();
-        final Connector connector = profile.getConnector();
+        ProvisioningTask task = profile.getTask();
+        ExternalResource resource = task.getResource();
+        Connector connector = profile.getConnector();
 
         for (Object membValue : getMembAttrValues(delta, connector)) {
-            Long userKey = syncUtilities.findMatchingAttributableKey(
-                    ObjectClass.ACCOUNT,
+            Long userKey = syncUtils.findMatchingAnyKey(
+                    anyTypeDAO.findUser(),
                     membValue.toString(),
                     profile.getTask().getResource(),
                     profile.getConnector());
@@ -289,20 +289,23 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * {@inheritDoc}
      */
     @Override
-    public <T extends AbstractSubjectTO> void after(
+    public <T extends AnyTO> void after(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
+            final T any,
             final ProvisioningResult result) throws JobExecutionException {
 
         if (!(profile.getTask() instanceof SyncTask)) {
             return;
         }
 
-        if (!(subject instanceof GroupTO) || profile.getTask().getResource().getUmapping() == null) {
-            super.after(profile, delta, subject, result);
+        if (!(any instanceof GroupTO)
+                || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()) == null
+                || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()).getMapping() == null) {
+
+            super.after(profile, delta, any, result);
         } else {
-            synchronizeMemberships(profile, delta, (GroupTO) subject);
+            synchronizeMemberships(profile, delta, (GroupTO) any);
         }
     }
 }


[25/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 4dfe2e9..72bfb33 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -26,17 +26,16 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.report.GroupReportletConf;
 import org.apache.syncope.common.lib.report.GroupReportletConf.Feature;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.xml.sax.ContentHandler;
@@ -52,7 +51,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
     private GroupDAO groupDAO;
 
     @Autowired
-    private SubjectSearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     @Autowired
     private GroupDataBinder groupDataBinder;
@@ -65,7 +64,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
         } else {
             result = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
                     SearchCondConverter.convert(conf.getMatchingCond()),
-                    page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), SubjectType.GROUP);
+                    page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), AnyTypeKind.GROUP);
         }
 
         return result;
@@ -75,19 +74,19 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
         return StringUtils.isBlank(conf.getMatchingCond())
                 ? groupDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
                 : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
-                        SearchCondConverter.convert(conf.getMatchingCond()), SubjectType.GROUP);
+                        SearchCondConverter.convert(conf.getMatchingCond()), AnyTypeKind.GROUP);
     }
 
-    private void doExtractResources(final ContentHandler handler, final AbstractSubjectTO subjectTO)
+    private void doExtractResources(final ContentHandler handler, final AnyTO anyTO)
             throws SAXException {
 
-        if (subjectTO.getResources().isEmpty()) {
-            LOG.debug("No resources found for {}[{}]", subjectTO.getClass().getSimpleName(), subjectTO.getKey());
+        if (anyTO.getResources().isEmpty()) {
+            LOG.debug("No resources found for {}[{}]", anyTO.getClass().getSimpleName(), anyTO.getKey());
         } else {
             AttributesImpl atts = new AttributesImpl();
             handler.startElement("", "", "resources", null);
 
-            for (String resourceName : subjectTO.getResources()) {
+            for (String resourceName : anyTO.getResources()) {
                 atts.clear();
 
                 atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, resourceName);
@@ -99,13 +98,13 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
         }
     }
 
-    private void doExtractAttributes(final ContentHandler handler, final AbstractAttributableTO attributableTO,
+    private void doExtractAttributes(final ContentHandler handler, final AnyTO anyTO,
             final Collection<String> attrs, final Collection<String> derAttrs, final Collection<String> virAttrs)
             throws SAXException {
 
         AttributesImpl atts = new AttributesImpl();
         if (!attrs.isEmpty()) {
-            Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
+            Map<String, AttrTO> attrMap = anyTO.getPlainAttrMap();
 
             handler.startElement("", "", "attributes", null);
             for (String attrName : attrs) {
@@ -122,7 +121,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "attribute");
@@ -131,7 +130,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
         }
 
         if (!derAttrs.isEmpty()) {
-            Map<String, AttrTO> derAttrMap = attributableTO.getDerAttrMap();
+            Map<String, AttrTO> derAttrMap = anyTO.getDerAttrMap();
 
             handler.startElement("", "", "derivedAttributes", null);
             for (String attrName : derAttrs) {
@@ -148,7 +147,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "derivedAttribute");
@@ -157,7 +156,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
         }
 
         if (!virAttrs.isEmpty()) {
-            Map<String, AttrTO> virAttrMap = attributableTO.getVirAttrMap();
+            Map<String, AttrTO> virAttrMap = anyTO.getVirAttrMap();
 
             handler.startElement("", "", "virtualAttributes", null);
             for (String attrName : virAttrs) {
@@ -174,7 +173,7 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "virtualAttribute");
@@ -236,13 +235,13 @@ public class GroupReportlet extends AbstractReportlet<GroupReportletConf> {
             if (conf.getFeatures().contains(Feature.users)) {
                 handler.startElement("", "", "users", null);
 
-                for (Membership memb : groupDAO.findMemberships(group)) {
+                for (UMembership memb : groupDAO.findUMemberships(group)) {
                     atts.clear();
 
                     atts.addAttribute("", "", "key", ReportXMLConst.XSD_LONG,
-                            String.valueOf(memb.getUser().getKey()));
+                            String.valueOf(memb.getLeftEnd().getKey()));
                     atts.addAttribute("", "", "username", ReportXMLConst.XSD_STRING,
-                            String.valueOf(memb.getUser().getUsername()));
+                            String.valueOf(memb.getLeftEnd().getUsername()));
 
                     handler.startElement("", "", "user", atts);
                     handler.endElement("", "", "user");

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index 575947d..b4087a7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -26,19 +26,18 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.report.UserReportletConf;
 import org.apache.syncope.common.lib.report.UserReportletConf.Feature;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 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.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.misc.search.SearchCondConverter;
 import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -55,7 +54,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
     private UserDAO userDAO;
 
     @Autowired
-    private SubjectSearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     @Autowired
     private UserDataBinder userDataBinder;
@@ -71,7 +70,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
         } else {
             result = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
                     SearchCondConverter.convert(conf.getMatchingCond()),
-                    page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), SubjectType.USER);
+                    page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), AnyTypeKind.USER);
         }
 
         return result;
@@ -81,19 +80,19 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
         return StringUtils.isBlank(conf.getMatchingCond())
                 ? userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS)
                 : searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
-                        SearchCondConverter.convert(conf.getMatchingCond()), SubjectType.USER);
+                        SearchCondConverter.convert(conf.getMatchingCond()), AnyTypeKind.USER);
     }
 
-    private void doExtractResources(final ContentHandler handler, final AbstractSubjectTO subjectTO)
+    private void doExtractResources(final ContentHandler handler, final AnyTO anyTO)
             throws SAXException {
 
-        if (subjectTO.getResources().isEmpty()) {
-            LOG.debug("No resources found for {}[{}]", subjectTO.getClass().getSimpleName(), subjectTO.getKey());
+        if (anyTO.getResources().isEmpty()) {
+            LOG.debug("No resources found for {}[{}]", anyTO.getClass().getSimpleName(), anyTO.getKey());
         } else {
             AttributesImpl atts = new AttributesImpl();
             handler.startElement("", "", "resources", null);
 
-            for (String resourceName : subjectTO.getResources()) {
+            for (String resourceName : anyTO.getResources()) {
                 atts.clear();
 
                 atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, resourceName);
@@ -105,13 +104,13 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
         }
     }
 
-    private void doExtractAttributes(final ContentHandler handler, final AbstractAttributableTO attributableTO,
+    private void doExtractAttributes(final ContentHandler handler, final AnyTO anyTO,
             final Collection<String> attrs, final Collection<String> derAttrs, final Collection<String> virAttrs)
             throws SAXException {
 
         AttributesImpl atts = new AttributesImpl();
         if (!attrs.isEmpty()) {
-            Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
+            Map<String, AttrTO> attrMap = anyTO.getPlainAttrMap();
 
             handler.startElement("", "", "attributes", null);
             for (String attrName : attrs) {
@@ -128,7 +127,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "attribute");
@@ -137,7 +136,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
         }
 
         if (!derAttrs.isEmpty()) {
-            Map<String, AttrTO> derAttrMap = attributableTO.getDerAttrMap();
+            Map<String, AttrTO> derAttrMap = anyTO.getDerAttrMap();
 
             handler.startElement("", "", "derivedAttributes", null);
             for (String attrName : derAttrs) {
@@ -154,7 +153,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "derivedAttribute");
@@ -163,7 +162,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
         }
 
         if (!virAttrs.isEmpty()) {
-            Map<String, AttrTO> virAttrMap = attributableTO.getVirAttrMap();
+            Map<String, AttrTO> virAttrMap = anyTO.getVirAttrMap();
 
             handler.startElement("", "", "virtualAttributes", null);
             for (String attrName : virAttrs) {
@@ -180,7 +179,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     }
                 } else {
                     LOG.debug("{} not found for {}[{}]", attrName,
-                            attributableTO.getClass().getSimpleName(), attributableTO.getKey());
+                            anyTO.getClass().getSimpleName(), anyTO.getKey());
                 }
 
                 handler.endElement("", "", "virtualAttribute");
@@ -272,21 +271,18 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     atts.clear();
 
                     atts.addAttribute("", "", "id", ReportXMLConst.XSD_LONG, String.valueOf(memb.getKey()));
-                    atts.addAttribute("", "", "groupId", ReportXMLConst.XSD_LONG, String.valueOf(memb.getGroupKey()));
+                    atts.addAttribute("", "", "groupId", ReportXMLConst.XSD_LONG, String.valueOf(memb.getRightKey()));
                     atts.addAttribute("", "", "groupName", ReportXMLConst.XSD_STRING, String.
                             valueOf(memb.getGroupName()));
                     handler.startElement("", "", "membership", atts);
 
-                    doExtractAttributes(handler, memb, memb.getPlainAttrMap().keySet(), memb.getDerAttrMap()
-                            .keySet(), memb.getVirAttrMap().keySet());
-
                     if (conf.getFeatures().contains(Feature.resources)) {
-                        Membership actualMemb = user.getMembership(memb.getGroupKey());
+                        UMembership actualMemb = user.getMembership(memb.getRightKey());
                         if (actualMemb == null) {
-                            LOG.warn("Unexpected: cannot find membership for group {} for user {}", memb.getGroupKey(),
+                            LOG.warn("Unexpected: cannot find membership for group {} for user {}", memb.getRightKey(),
                                     user);
                         } else {
-                            doExtractResources(handler, groupDataBinder.getGroupTO(actualMemb.getGroup()));
+                            doExtractResources(handler, groupDataBinder.getGroupTO(actualMemb.getRightEnd()));
                         }
                     }
 
@@ -305,7 +301,6 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
     }
 
     private void doExtractConf(final ContentHandler handler) throws SAXException {
-
         AttributesImpl atts = new AttributesImpl();
         handler.startElement("", "", "configurations", null);
         handler.startElement("", "", "userAttributes", atts);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
index 736d1d3..64aaa09 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
@@ -48,7 +48,6 @@ import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.TaskType;
@@ -57,15 +56,15 @@ import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Notification;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.logic.notification.NotificationJob;
 import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -124,7 +123,7 @@ public class NotificationTest {
     private NotificationDAO notificationDAO;
 
     @Autowired
-    private RealmDAO realmDAO;
+    private AnyTypeDAO anyTypeDAO;
 
     @Autowired
     private TaskDAO taskDAO;
@@ -156,9 +155,6 @@ public class NotificationTest {
     @Autowired
     private EntityFactory entityFactory;
 
-    @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
-
     @BeforeClass
     public static void startGreenMail() {
         ServerSetup[] config = new ServerSetup[2];
@@ -264,7 +260,13 @@ public class NotificationTest {
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
         notification.setRecipients(new UserFiqlSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
 
@@ -286,7 +288,7 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
@@ -322,7 +324,13 @@ public class NotificationTest {
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
         notification.setRecipients(new UserFiqlSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
 
@@ -343,7 +351,7 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
@@ -374,7 +382,6 @@ public class NotificationTest {
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(null);
         notification.setRecipients(new UserFiqlSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
 
@@ -396,7 +403,7 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
@@ -424,7 +431,6 @@ public class NotificationTest {
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(null);
         notification.setRecipients(new UserFiqlSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
 
@@ -446,15 +452,16 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
 
         // 3. Set number of retries
         CPlainAttr maxRetries = entityFactory.newEntity(CPlainAttr.class);
-        maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries", CPlainSchema.class));
-        maxRetries.addValue("5", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+        maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries"));
+        CPlainAttrValue maxRetriesValue = entityFactory.newEntity(CPlainAttrValue.class);
+        maxRetries.add("5", maxRetriesValue);
         confDAO.save(maxRetries);
         confDAO.flush();
 
@@ -482,8 +489,9 @@ public class NotificationTest {
 
         // 8. reset number of retries
         maxRetries = entityFactory.newEntity(CPlainAttr.class);
-        maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries", CPlainSchema.class));
-        maxRetries.addValue("0", attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+        maxRetries.setSchema(plainSchemaDAO.find("notification.maxRetries"));
+        maxRetriesValue = entityFactory.newEntity(CPlainAttrValue.class);
+        maxRetries.add("0", maxRetriesValue);
         confDAO.save(maxRetries);
         confDAO.flush();
     }
@@ -493,7 +501,13 @@ public class NotificationTest {
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
         notification.setRecipients(new UserFiqlSearchConditionBuilder().inGroups(8L).query());
         notification.setSelfAsRecipient(true);
 
@@ -517,7 +531,7 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
@@ -552,7 +566,13 @@ public class NotificationTest {
         // 1. create suitable disabled notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
-        notification.setUserAbout(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set(new UserFiqlSearchConditionBuilder().inGroups(7L).query());
+
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
@@ -578,7 +598,7 @@ public class NotificationTest {
         // 2. create user
         UserTO userTO = getUniqueSampleTO(MAIL_ADDRESS);
         MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setGroupKey(7);
+        membershipTO.setRightKey(7);
         userTO.getMemberships().add(membershipTO);
 
         userLogic.create(userTO, true);
@@ -592,11 +612,16 @@ public class NotificationTest {
 
     @Test
     public void issueSYNCOPE446() throws Exception {
-
         // 1. create suitable notification for subsequent tests
         Notification notification = entityFactory.newEntity(Notification.class);
         notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
-        notification.setGroupAbout(new GroupFiqlSearchConditionBuilder().is("name").equalTo("group446").query());
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findGroup());
+        about.set(new GroupFiqlSearchConditionBuilder().is("name").equalTo("group446").query());
+
         notification.setSelfAsRecipient(false);
 
         notification.setRecipientAttrName("email");

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
index 719a680..30341bd 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/ConnObjectUtils.java
@@ -32,17 +32,15 @@ import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.AttributableOperations;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
@@ -51,15 +49,12 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -70,14 +65,20 @@ import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
 import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+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.Realm;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.identityconnectors.common.Base64;
 import org.identityconnectors.common.security.GuardedByteArray;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.OperationOptions;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
@@ -90,9 +91,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Component
 public class ConnObjectUtils {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtils.class);
 
     @Autowired
@@ -102,6 +100,9 @@ public class ConnObjectUtils {
     private UserDAO userDAO;
 
     @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     private GroupDAO groupDAO;
 
     @Autowired
@@ -113,6 +114,9 @@ public class ConnObjectUtils {
     @Autowired
     private PasswordGenerator pwdGen;
 
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
     private final Encryptor encryptor = Encryptor.getInstance();
 
     /**
@@ -121,40 +125,25 @@ public class ConnObjectUtils {
     @Autowired
     private VirAttrCache virAttrCache;
 
-    public ObjectClass fromSubject(final Subject<?, ?, ?> subject) {
-        if (subject == null) {
-            throw new IllegalArgumentException("No ObjectClass could be provided for " + subject);
-        }
-
-        ObjectClass result = null;
-        if (subject instanceof User) {
-            result = ObjectClass.ACCOUNT;
-        }
-        if (subject instanceof Group) {
-            result = ObjectClass.GROUP;
-        }
-
-        return result;
-    }
-
     /**
-     * Build a UserTO / GroupTO out of connector object attributes and schema mapping.
+     * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
      *
      * @param obj connector object
      * @param syncTask synchronization task
-     * @param attrUtils AttributableUtils
-     * @param <T> user/group
+     * @param provision provision information
+     * @param anyUtils utils
+     * @param <T> any object
      * @return UserTO for the user to be created
      */
     @Transactional(readOnly = true)
-    public <T extends AbstractSubjectTO> T getSubjectTO(final ConnectorObject obj, final SyncTask syncTask,
-            final AttributableUtils attrUtils) {
+    public <T extends AnyTO> T getAnyTO(
+            final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
 
-        T subjectTO = getSubjectTOFromConnObject(obj, syncTask, attrUtils);
+        T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
 
         // (for users) if password was not set above, generate
-        if (subjectTO instanceof UserTO && StringUtils.isBlank(((UserTO) subjectTO).getPassword())) {
-            final UserTO userTO = (UserTO) subjectTO;
+        if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
+            final UserTO userTO = (UserTO) anyTO;
 
             List<PasswordPolicySpec> ppSpecs = new ArrayList<>();
 
@@ -189,62 +178,54 @@ public class ConnObjectUtils {
             userTO.setPassword(password);
         }
 
-        return subjectTO;
+        return anyTO;
     }
 
     /**
      * Build an UserMod out of connector object attributes and schema mapping.
      *
-     * @param key user to be updated
+     * @param key any object to be updated
      * @param obj connector object
-     * @param original subject to get diff from
+     * @param original any object to get diff from
      * @param syncTask synchronization task
-     * @param attrUtils AttributableUtil
-     * @param <T> user/group
-     * @return modifications for the user/group to be updated
+     * @param provision provision information
+     * @param anyUtils utils
+     * @param <T> any object
+     * @return modifications for the any object to be updated
      */
     @SuppressWarnings("unchecked")
     @Transactional(readOnly = true)
-    public <T extends AbstractAttributableMod> T getAttributableMod(final Long key, final ConnectorObject obj,
-            final AbstractAttributableTO original, final SyncTask syncTask, final AttributableUtils attrUtils) {
+    public <T extends AnyMod> T getAnyMod(final Long key, final ConnectorObject obj,
+            final AnyTO original, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
 
-        final AbstractAttributableTO updated = getSubjectTOFromConnObject(obj, syncTask, attrUtils);
+        AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
         updated.setKey(key);
 
-        if (AttributableType.USER == attrUtils.getType()) {
+        if (AnyTypeKind.USER == anyUtils.getAnyTypeKind()) {
             // update password if and only if password is really changed
-            final User user = userDAO.authFetch(key);
+            User user = userDAO.authFind(key);
             if (StringUtils.isBlank(((UserTO) updated).getPassword())
                     || encryptor.verify(((UserTO) updated).getPassword(),
                             user.getCipherAlgorithm(), user.getPassword())) {
 
                 ((UserTO) updated).setPassword(null);
             }
-
-            for (MembershipTO membTO : ((UserTO) updated).getMemberships()) {
-                Membership memb = user.getMembership(membTO.getGroupKey());
-                if (memb != null) {
-                    membTO.setKey(memb.getKey());
-                }
-            }
-
-            return (T) AttributableOperations.diff(((UserTO) updated), ((UserTO) original), true);
-        }
-        if (AttributableType.GROUP == attrUtils.getType()) {
-            return (T) AttributableOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
+            return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
+        } else if (AnyTypeKind.GROUP == anyUtils.getAnyTypeKind()) {
+            return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
         }
 
         return null;
     }
 
-    private <T extends AbstractSubjectTO> T getSubjectTOFromConnObject(final ConnectorObject obj,
-            final SyncTask syncTask, final AttributableUtils attrUtils) {
+    private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
+            final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
 
-        final T subjectTO = attrUtils.newSubjectTO();
+        T anyTO = anyUtils.newAnyTO();
 
         // 1. fill with data from connector object
-        subjectTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
-        for (MappingItem item : attrUtils.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)) {
+        anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
+        for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
             Attribute attr = obj.getAttributeByName(item.getExtAttrName());
 
             AttrTO attrTO;
@@ -254,16 +235,16 @@ public class ConnObjectUtils {
                     break;
 
                 case Password:
-                    if (subjectTO instanceof UserTO && attr != null && attr.getValue() != null
+                    if (anyTO instanceof UserTO && attr != null && attr.getValue() != null
                             && !attr.getValue().isEmpty()) {
 
-                        ((UserTO) subjectTO).setPassword(getPassword(attr.getValue().get(0)));
+                        ((UserTO) anyTO).setPassword(getPassword(attr.getValue().get(0)));
                     }
                     break;
 
                 case Username:
-                    if (subjectTO instanceof UserTO) {
-                        ((UserTO) subjectTO).setUsername(attr == null || attr.getValue().isEmpty()
+                    if (anyTO instanceof UserTO) {
+                        ((UserTO) anyTO).setUsername(attr == null || attr.getValue().isEmpty()
                                 || attr.getValue().get(0) == null
                                         ? null
                                         : attr.getValue().get(0).toString());
@@ -271,8 +252,8 @@ public class ConnObjectUtils {
                     break;
 
                 case GroupName:
-                    if (subjectTO instanceof GroupTO) {
-                        ((GroupTO) subjectTO).setName(attr == null || attr.getValue().isEmpty()
+                    if (anyTO instanceof GroupTO) {
+                        ((GroupTO) anyTO).setName(attr == null || attr.getValue().isEmpty()
                                 || attr.getValue().get(0) == null
                                         ? null
                                         : attr.getValue().get(0).toString());
@@ -280,7 +261,7 @@ public class ConnObjectUtils {
                     break;
 
                 case GroupOwnerSchema:
-                    if (subjectTO instanceof GroupTO && attr != null) {
+                    if (anyTO instanceof GroupTO && attr != null) {
                         // using a special attribute (with schema "", that will be ignored) for carrying the
                         // GroupOwnerSchema value
                         attrTO = new AttrTO();
@@ -291,7 +272,7 @@ public class ConnObjectUtils {
                             attrTO.getValues().add(attr.getValue().get(0).toString());
                         }
 
-                        ((GroupTO) subjectTO).getPlainAttrs().add(attrTO);
+                        ((GroupTO) anyTO).getPlainAttrs().add(attrTO);
                     }
                     break;
 
@@ -300,7 +281,7 @@ public class ConnObjectUtils {
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
 
-                    PlainSchema schema = plainSchemaDAO.find(item.getIntAttrName(), attrUtils.plainSchemaClass());
+                    PlainSchema schema = plainSchemaDAO.find(item.getIntAttrName());
 
                     for (Object value : attr == null || attr.getValue() == null
                             ? Collections.emptyList()
@@ -308,7 +289,7 @@ public class ConnObjectUtils {
 
                         AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
                         if (value != null) {
-                            final PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+                            final PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
                             switch (schemaType) {
                                 case String:
                                     attrValue.setStringValue(value.toString());
@@ -332,14 +313,14 @@ public class ConnObjectUtils {
                         }
                     }
 
-                    subjectTO.getPlainAttrs().add(attrTO);
+                    anyTO.getPlainAttrs().add(attrTO);
                     break;
 
                 case UserDerivedSchema:
                 case GroupDerivedSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
-                    subjectTO.getDerAttrs().add(attrTO);
+                    anyTO.getDerAttrs().add(attrTO);
                     break;
 
                 case UserVirtualSchema:
@@ -356,7 +337,7 @@ public class ConnObjectUtils {
                         }
                     }
 
-                    subjectTO.getVirAttrs().add(attrTO);
+                    anyTO.getVirAttrs().add(attrTO);
                     break;
 
                 default:
@@ -364,79 +345,59 @@ public class ConnObjectUtils {
         }
 
         // 2. add data from defined template (if any)
-        AbstractSubjectTO template = AttributableType.USER == attrUtils.getType()
-                ? syncTask.getUserTemplate() : syncTask.getGroupTemplate();
+        AnyTemplate anyTypeTemplate = syncTask.getTemplate(provision.getAnyType());
+        if (anyTypeTemplate != null) {
+            AnyTO template = anyTypeTemplate.get();
 
-        if (template != null) {
             if (template.getRealm() != null) {
-                subjectTO.setRealm(template.getRealm());
+                anyTO.setRealm(template.getRealm());
             }
 
             if (template instanceof UserTO) {
                 if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
-                    String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), subjectTO);
+                    String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
                     if (StringUtils.isNotBlank(evaluated)) {
-                        ((UserTO) subjectTO).setUsername(evaluated);
+                        ((UserTO) anyTO).setUsername(evaluated);
                     }
                 }
 
                 if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
-                    String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), subjectTO);
+                    String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO);
                     if (StringUtils.isNotBlank(evaluated)) {
-                        ((UserTO) subjectTO).setPassword(evaluated);
+                        ((UserTO) anyTO).setPassword(evaluated);
                     }
                 }
-
-                Map<Long, MembershipTO> currentMembs = ((UserTO) subjectTO).getMembershipMap();
-                for (MembershipTO membTO : ((UserTO) template).getMemberships()) {
-                    MembershipTO membTBU;
-                    if (currentMembs.containsKey(membTO.getGroupKey())) {
-                        membTBU = currentMembs.get(membTO.getGroupKey());
-                    } else {
-                        membTBU = new MembershipTO();
-                        membTBU.setGroupKey(membTO.getGroupKey());
-                        ((UserTO) subjectTO).getMemberships().add(membTBU);
-                    }
-                    fillFromTemplate(membTBU, membTO);
-                }
             }
             if (template instanceof GroupTO) {
                 if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
-                    String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), subjectTO);
+                    String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
                     if (StringUtils.isNotBlank(evaluated)) {
-                        ((GroupTO) subjectTO).setName(evaluated);
+                        ((GroupTO) anyTO).setName(evaluated);
                     }
                 }
 
                 if (((GroupTO) template).getUserOwner() != null) {
                     final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
                     if (userOwner != null) {
-                        ((GroupTO) subjectTO).setUserOwner(userOwner.getKey());
+                        ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
                     }
                 }
                 if (((GroupTO) template).getGroupOwner() != null) {
                     final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
                     if (groupOwner != null) {
-                        ((GroupTO) subjectTO).setGroupOwner(groupOwner.getKey());
+                        ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
                     }
                 }
-
-                ((GroupTO) subjectTO).getGPlainAttrTemplates().addAll(((GroupTO) template).getGPlainAttrTemplates());
-                ((GroupTO) subjectTO).getGDerAttrTemplates().addAll(((GroupTO) template).getGDerAttrTemplates());
-                ((GroupTO) subjectTO).getGVirAttrTemplates().addAll(((GroupTO) template).getGVirAttrTemplates());
-                ((GroupTO) subjectTO).getMPlainAttrTemplates().addAll(((GroupTO) template).getMPlainAttrTemplates());
-                ((GroupTO) subjectTO).getMDerAttrTemplates().addAll(((GroupTO) template).getMDerAttrTemplates());
-                ((GroupTO) subjectTO).getMVirAttrTemplates().addAll(((GroupTO) template).getMVirAttrTemplates());
             }
 
-            fillFromTemplate(subjectTO, template);
+            fillFromTemplate(anyTO, template);
 
             for (String resource : template.getResources()) {
-                subjectTO.getResources().add(resource);
+                anyTO.getResources().add(resource);
             }
         }
 
-        return subjectTO;
+        return anyTO;
     }
 
     /**
@@ -509,41 +470,41 @@ public class ConnObjectUtils {
     /**
      * Query connected external resources for values to populated virtual attributes associated with the given owner.
      *
-     * @param owner user or group
-     * @param attrUtils attributable util
+     * @param any any object
      */
-    public void retrieveVirAttrValues(final Attributable<?, ?, ?> owner, final AttributableUtils attrUtils) {
-        final ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        final ConnectorFactory connFactory = context.getBean(ConnectorFactory.class);
+    public void retrieveVirAttrValues(final Any<?, ?, ?> any) {
+        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+        ConnectorFactory connFactory = context.getBean(ConnectorFactory.class);
 
-        final IntMappingType type = attrUtils.getType() == AttributableType.USER
-                ? IntMappingType.UserVirtualSchema : attrUtils.getType() == AttributableType.GROUP
-                        ? IntMappingType.GroupVirtualSchema : IntMappingType.MembershipVirtualSchema;
+        IntMappingType type = any.getType().getKind() == AnyTypeKind.USER
+                ? IntMappingType.UserVirtualSchema
+                : any.getType().getKind() == AnyTypeKind.GROUP
+                        ? IntMappingType.GroupVirtualSchema
+                        : IntMappingType.AnyVirtualSchema;
 
-        final Map<String, ConnectorObject> externalResources = new HashMap<>();
+        Map<String, ConnectorObject> resources = new HashMap<>();
 
         // -----------------------
         // Retrieve virtual attribute values if and only if they have not been retrieved yet
         // -----------------------
-        for (VirAttr virAttr : owner.getVirAttrs()) {
+        for (VirAttr<?> virAttr : any.getVirAttrs()) {
             // reset value set
             if (virAttr.getValues().isEmpty()) {
-                retrieveVirAttrValue(owner, virAttr, attrUtils, type, externalResources, connFactory);
+                retrieveVirAttrValue(any, virAttr, type, resources, connFactory);
             }
         }
         // -----------------------
     }
 
     private void retrieveVirAttrValue(
-            final Attributable<?, ?, ?> owner,
-            final VirAttr virAttr,
-            final AttributableUtils attrUtils,
+            final Any<?, ?, ?> any,
+            final VirAttr<?> virAttr,
             final IntMappingType type,
             final Map<String, ConnectorObject> externalResources,
             final ConnectorFactory connFactory) {
 
-        final String schemaName = virAttr.getSchema().getKey();
-        final VirAttrCacheValue virAttrCacheValue = virAttrCache.get(attrUtils.getType(), owner.getKey(), schemaName);
+        String schemaName = virAttr.getSchema().getKey();
+        VirAttrCacheValue virAttrCacheValue = virAttrCache.get(any.getType().getKey(), any.getKey(), schemaName);
 
         LOG.debug("Retrieve values for virtual attribute {} ({})", schemaName, type);
 
@@ -558,147 +519,147 @@ public class ConnObjectUtils {
 
             VirAttrCacheValue toBeCached = new VirAttrCacheValue();
 
-            // SYNCOPE-458 if virattr owner is a Membership, owner must become user involved in membership because 
-            // membership mapping is contained in user mapping
-            Subject<?, ?, ?> realOwner = owner instanceof Membership
-                    ? ((Membership) owner).getUser()
-                    : (Subject) owner;
-
-            Collection<ExternalResource> targetResources = owner instanceof Membership
-                    ? getTargetResources(virAttr, type, attrUtils, userDAO.findAllResources((User) realOwner))
-                    : getTargetResources(virAttr, type, attrUtils);
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+            Collection<ExternalResource> targetResources = getTargetResources(virAttr, type, anyUtils, any.getType());
 
             for (ExternalResource resource : targetResources) {
-                LOG.debug("Search values into {}", resource.getKey());
-                try {
-                    List<MappingItem> mappings = attrUtils.getMappingItems(resource, MappingPurpose.BOTH);
-
-                    ConnectorObject connectorObject;
-                    if (externalResources.containsKey(resource.getKey())) {
-                        connectorObject = externalResources.get(resource.getKey());
-                    } else {
-                        LOG.debug("Perform connection to {}", resource.getKey());
-                        final String accountId = attrUtils.getAccountIdItem(resource) == null
-                                ? null
-                                : MappingUtils.getAccountIdValue(
-                                        realOwner, resource, attrUtils.getAccountIdItem(resource));
-
-                        if (StringUtils.isBlank(accountId)) {
-                            throw new IllegalArgumentException("No AccountId found for " + resource.getKey());
-                        }
+                Provision provision = resource.getProvision(any.getType());
+                LOG.debug("Search values into {},{}", resource, provision);
 
-                        Connector connector = connFactory.getConnector(resource);
+                if (provision != null) {
+                    try {
+                        List<MappingItem> mappings = anyUtils.getMappingItems(provision, MappingPurpose.BOTH);
 
-                        OperationOptions oo =
-                                connector.getOperationOptions(MappingUtils.getMatchingMappingItems(mappings, type));
+                        ConnectorObject connectorObject;
+                        if (externalResources.containsKey(resource.getKey())) {
+                            connectorObject = externalResources.get(resource.getKey());
+                        } else {
+                            LOG.debug("Perform connection to {}", resource.getKey());
+                            String connObjectKey = anyUtils.getConnObjectKeyItem(provision) == null
+                                    ? null
+                                    : MappingUtils.getConnObjectKeyValue(any, provision);
 
-                        connectorObject = connector.getObject(fromSubject(realOwner), new Uid(accountId), oo);
-                        externalResources.put(resource.getKey(), connectorObject);
-                    }
+                            if (StringUtils.isBlank(connObjectKey)) {
+                                throw new IllegalArgumentException("No AccountId found for " + resource.getKey());
+                            }
+
+                            Connector connector = connFactory.getConnector(resource);
+
+                            OperationOptions oo =
+                                    connector.getOperationOptions(MappingUtils.getMatchingMappingItems(mappings, type));
+
+                            connectorObject =
+                                    connector.getObject(provision.getObjectClass(), new Uid(connObjectKey), oo);
+                            externalResources.put(resource.getKey(), connectorObject);
+                        }
 
-                    if (connectorObject != null) {
-                        // ask for searched virtual attribute value
-                        Collection<MappingItem> virAttrMappings =
-                                MappingUtils.getMatchingMappingItems(mappings, schemaName, type);
+                        if (connectorObject != null) {
+                            // ask for searched virtual attribute value
+                            Collection<MappingItem> virAttrMappings =
+                                    MappingUtils.getMatchingMappingItems(mappings, schemaName, type);
 
-                        // the same virtual attribute could be mapped with one or more external attribute 
-                        for (MappingItem mapping : virAttrMappings) {
-                            final Attribute attribute = connectorObject.getAttributeByName(mapping.getExtAttrName());
+                            // the same virtual attribute could be mapped with one or more external attribute 
+                            for (MappingItem mapping : virAttrMappings) {
+                                Attribute attribute = connectorObject.getAttributeByName(mapping.getExtAttrName());
 
-                            if (attribute != null && attribute.getValue() != null) {
-                                for (Object obj : attribute.getValue()) {
-                                    if (obj != null) {
-                                        virAttr.getValues().add(obj.toString());
+                                if (attribute != null && attribute.getValue() != null) {
+                                    for (Object obj : attribute.getValue()) {
+                                        if (obj != null) {
+                                            virAttr.getValues().add(obj.toString());
+                                        }
                                     }
                                 }
                             }
-                        }
 
-                        toBeCached.setResourceValues(resource.getKey(), new HashSet<>(virAttr.getValues()));
+                            toBeCached.setResourceValues(resource.getKey(), new HashSet<>(virAttr.getValues()));
 
-                        LOG.debug("Retrieved values {}", virAttr.getValues());
-                    }
-                } catch (Exception e) {
-                    LOG.error("Error reading connector object from {}", resource.getKey(), e);
-
-                    if (virAttrCacheValue != null) {
-                        toBeCached.forceExpiring();
-                        LOG.debug("Search for a cached value (even expired!) ...");
-                        final Set<String> cachedValues = virAttrCacheValue.getValues(resource.getKey());
-                        if (cachedValues != null) {
-                            LOG.debug("Use cached value {}", cachedValues);
-                            virAttr.getValues().addAll(cachedValues);
-                            toBeCached.setResourceValues(resource.getKey(), new HashSet<>(cachedValues));
+                            LOG.debug("Retrieved values {}", virAttr.getValues());
+                        }
+                    } catch (Exception e) {
+                        LOG.error("Error reading connector object from {}", resource.getKey(), e);
+
+                        if (virAttrCacheValue != null) {
+                            toBeCached.forceExpiring();
+                            LOG.debug("Search for a cached value (even expired!) ...");
+                            final Set<String> cachedValues = virAttrCacheValue.getValues(resource.getKey());
+                            if (cachedValues != null) {
+                                LOG.debug("Use cached value {}", cachedValues);
+                                virAttr.getValues().addAll(cachedValues);
+                                toBeCached.setResourceValues(resource.getKey(), new HashSet<>(cachedValues));
+                            }
                         }
                     }
                 }
             }
 
-            virAttrCache.put(attrUtils.getType(), owner.getKey(), schemaName, toBeCached);
+            virAttrCache.put(any.getType().getKey(), any.getKey(), schemaName, toBeCached);
         }
     }
 
     private Collection<ExternalResource> getTargetResources(
-            final VirAttr attr, final IntMappingType type, final AttributableUtils attrUtils) {
+            final VirAttr<?> attr, final IntMappingType type, final AnyUtils anyUtils, final AnyType anyType) {
 
         Iterable<? extends ExternalResource> iterable = attr.getOwner() instanceof User
                 ? userDAO.findAllResources((User) attr.getOwner())
-                : attr.getOwner() instanceof Group
-                        ? ((Group) attr.getOwner()).getResources()
-                        : Collections.<ExternalResource>emptySet();
-        return getTargetResources(attr, type, attrUtils, iterable);
+                : attr.getOwner() instanceof AnyObject
+                        ? anyObjectDAO.findAllResources((AnyObject) attr.getOwner())
+                        : attr.getOwner() instanceof Group
+                                ? ((Group) attr.getOwner()).getResources()
+                                : Collections.<ExternalResource>emptySet();
+        return getTargetResources(attr, type, anyUtils, iterable, anyType);
     }
 
-    private Collection<ExternalResource> getTargetResources(final VirAttr attr, final IntMappingType type,
-            final AttributableUtils attrUtils, final Iterable<? extends ExternalResource> ownerResources) {
+    private Collection<ExternalResource> getTargetResources(final VirAttr<?> attr, final IntMappingType type,
+            final AnyUtils anyUtils, final Iterable<? extends ExternalResource> ownerResources, final AnyType anyType) {
 
         return CollectionUtils.select(ownerResources, new Predicate<ExternalResource>() {
 
             @Override
             public boolean evaluate(final ExternalResource resource) {
-                return !MappingUtils.getMatchingMappingItems(
-                        attrUtils.getMappingItems(resource, MappingPurpose.BOTH),
-                        attr.getSchema().getKey(), type).isEmpty();
+                return resource.getProvision(anyType) != null
+                        && !MappingUtils.getMatchingMappingItems(
+                                anyUtils.getMappingItems(resource.getProvision(anyType), MappingPurpose.BOTH),
+                                attr.getSchema().getKey(), type).isEmpty();
             }
         });
     }
 
-    private void fillFromTemplate(final AbstractAttributableTO attributableTO, final AbstractAttributableTO template) {
-        Map<String, AttrTO> currentAttrMap = attributableTO.getPlainAttrMap();
+    private void fillFromTemplate(final AnyTO anyTO, final AnyTO template) {
+        Map<String, AttrTO> currentAttrMap = anyTO.getPlainAttrMap();
         for (AttrTO templateAttr : template.getPlainAttrs()) {
             if (templateAttr.getValues() != null && !templateAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateAttr.getSchema())
                     || currentAttrMap.get(templateAttr.getSchema()).getValues().isEmpty())) {
 
-                attributableTO.getPlainAttrs().add(evaluateAttrTemplate(attributableTO, templateAttr));
+                anyTO.getPlainAttrs().add(evaluateAttrTemplate(anyTO, templateAttr));
             }
         }
 
-        currentAttrMap = attributableTO.getDerAttrMap();
+        currentAttrMap = anyTO.getDerAttrMap();
         for (AttrTO templateDerAttr : template.getDerAttrs()) {
             if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
-                attributableTO.getDerAttrs().add(templateDerAttr);
+                anyTO.getDerAttrs().add(templateDerAttr);
             }
         }
 
-        currentAttrMap = attributableTO.getVirAttrMap();
+        currentAttrMap = anyTO.getVirAttrMap();
         for (AttrTO templateVirAttr : template.getVirAttrs()) {
             if (templateVirAttr.getValues() != null && !templateVirAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
                     || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
 
-                attributableTO.getVirAttrs().add(evaluateAttrTemplate(attributableTO, templateVirAttr));
+                anyTO.getVirAttrs().add(evaluateAttrTemplate(anyTO, templateVirAttr));
             }
         }
     }
 
-    private AttrTO evaluateAttrTemplate(final AbstractAttributableTO attributableTO, final AttrTO template) {
+    private AttrTO evaluateAttrTemplate(final AnyTO anyTO, final AttrTO template) {
         AttrTO result = new AttrTO();
         result.setSchema(template.getSchema());
 
         if (template.getValues() != null && !template.getValues().isEmpty()) {
             for (String value : template.getValues()) {
-                String evaluated = JexlUtils.evaluate(value, attributableTO);
+                String evaluated = JexlUtils.evaluate(value, anyTO);
                 if (StringUtils.isNotBlank(evaluated)) {
                     result.getValues().add(evaluated);
                 }


[11/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
deleted file mode 100644
index 22e7494..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
+++ /dev/null
@@ -1,483 +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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.GroupCond;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class SubjectSearchTest extends AbstractTest {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private SubjectSearchDAO searchDAO;
-
-    @Test
-    public void userMatch() {
-        User user = userDAO.find(1L);
-        assertNotNull(user);
-
-        GroupCond groupCond = new GroupCond();
-        groupCond.setGroupKey(5L);
-        assertFalse(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), SubjectType.USER));
-
-        groupCond.setGroupKey(1L);
-        assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), SubjectType.USER));
-
-        RoleCond roleCond = new RoleCond();
-        roleCond.setRoleKey(3L);
-        assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(roleCond), SubjectType.USER));
-    }
-
-    @Test
-    public void groupMatch() {
-        Group group = groupDAO.find(1L);
-        assertNotNull(group);
-
-        AttributeCond attrCond = new AttributeCond();
-        attrCond.setSchema("show");
-        attrCond.setType(AttributeCond.Type.ISNOTNULL);
-
-        assertTrue(searchDAO.matches(group, SearchCond.getLeafCond(attrCond), SubjectType.GROUP));
-    }
-
-    @Test
-    public void searchWithLikeCondition() {
-        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond.setSchema("fullname");
-        fullnameLeafCond.setExpression("%o%");
-
-        GroupCond groupCond = new GroupCond();
-        groupCond.setGroupKey(1L);
-
-        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
-        loginDateCond.setSchema("loginDate");
-        loginDateCond.setExpression("2009-05-26");
-
-        SearchCond subCond = SearchCond.getAndCond(SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(
-                groupCond));
-
-        assertTrue(subCond.isValid());
-
-        SearchCond cond = SearchCond.getAndCond(subCond, SearchCond.getLeafCond(loginDateCond));
-
-        assertTrue(cond.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-    }
-
-    @Test
-    public void searchWithNotCondition() {
-        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.EQ);
-        fullnameLeafCond.setSchema("fullname");
-        fullnameLeafCond.setExpression("Giuseppe Verdi");
-
-        SearchCond cond = SearchCond.getNotLeafCond(fullnameLeafCond);
-        assertTrue(cond.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(4, users.size());
-
-        Set<Long> ids = new HashSet<>(users.size());
-        for (User user : users) {
-            ids.add(user.getKey());
-        }
-        assertTrue(ids.contains(1L));
-        assertTrue(ids.contains(3L));
-    }
-
-    @Test
-    public void searchByBoolean() {
-        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
-        coolLeafCond.setSchema("cool");
-        coolLeafCond.setExpression("true");
-
-        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
-        assertTrue(cond.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-
-        assertEquals(Long.valueOf(4L), users.get(0).getKey());
-    }
-
-    @Test
-    public void searchByPageAndSize() {
-        AttributeCond fullnameLeafCond = new AttributeCond(AttributeCond.Type.LIKE);
-        fullnameLeafCond.setSchema("fullname");
-        fullnameLeafCond.setExpression("%o%");
-
-        GroupCond groupCond = new GroupCond();
-        groupCond.setGroupKey(1L);
-
-        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
-        loginDateCond.setSchema("loginDate");
-        loginDateCond.setExpression("2009-05-26");
-
-        SearchCond subCond = SearchCond.getAndCond(
-                SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(groupCond));
-
-        assertTrue(subCond.isValid());
-
-        SearchCond cond = SearchCond.getAndCond(subCond, SearchCond.getLeafCond(loginDateCond));
-
-        assertTrue(cond.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                cond, 1, 2, Collections.<OrderByClause>emptyList(),
-                SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-
-        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                cond, 2, 2, Collections.<OrderByClause>emptyList(),
-                SubjectType.USER);
-        assertNotNull(users);
-        assertTrue(users.isEmpty());
-    }
-
-    @Test
-    public void searchByGroup() {
-        GroupCond groupCond = new GroupCond();
-        groupCond.setGroupKey(1L);
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getLeafCond(groupCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(2, users.size());
-
-        groupCond = new GroupCond();
-        groupCond.setGroupKey(5L);
-
-        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getNotLeafCond(groupCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(5, users.size());
-    }
-
-    @Test
-    public void searchByRole() {
-        RoleCond roleCond = new RoleCond();
-        roleCond.setRoleKey(3L);
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getLeafCond(roleCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-    }
-
-    @Test
-    public void searchByIsNull() {
-        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.ISNULL);
-        coolLeafCond.setSchema("cool");
-
-        List<User> users = searchDAO.search(
-                SyncopeConstants.FULL_ADMIN_REALMS, SearchCond.getLeafCond(coolLeafCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(4, users.size());
-
-        coolLeafCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
-        coolLeafCond.setSchema("cool");
-
-        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getLeafCond(coolLeafCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-    }
-
-    @Test
-    public void searchByResource() {
-        ResourceCond ws2 = new ResourceCond();
-        ws2.setResourceName("ws-target-resource-2");
-
-        ResourceCond ws1 = new ResourceCond();
-        ws1.setResourceName("ws-target-resource-list-mappings-2");
-
-        SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), SearchCond.getLeafCond(ws1));
-        assertTrue(searchCondition.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-    }
-
-    @Test
-    public void searchByBooleanSubjectCond() {
-        AttributeCond booleanCond = new AttributeCond(SubjectCond.Type.EQ);
-        booleanCond.setSchema("show");
-        booleanCond.setExpression("true");
-
-        List<Group> matchingGroups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getLeafCond(booleanCond), SubjectType.GROUP);
-        assertNotNull(matchingGroups);
-        assertFalse(matchingGroups.isEmpty());
-    }
-
-    @Test
-    public void searchByUsernameAndKey() {
-        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
-        usernameLeafCond.setSchema("username");
-        usernameLeafCond.setExpression("%ini");
-
-        SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
-        idRightCond.setSchema("key");
-        idRightCond.setExpression("2");
-
-        SearchCond searchCondition = SearchCond.getAndCond(
-                SearchCond.getLeafCond(usernameLeafCond),
-                SearchCond.getLeafCond(idRightCond));
-
-        List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, SubjectType.USER);
-
-        assertNotNull(matchingUsers);
-        assertEquals(1, matchingUsers.size());
-        assertEquals("rossini", matchingUsers.iterator().next().getUsername());
-        assertEquals(1L, matchingUsers.iterator().next().getKey(), 0);
-    }
-
-    @Test
-    public void searchByGroupNameAndKey() {
-        SubjectCond groupNameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
-        groupNameLeafCond.setSchema("name");
-        groupNameLeafCond.setExpression("root");
-
-        SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
-        idRightCond.setSchema("key");
-        idRightCond.setExpression("2");
-
-        SearchCond searchCondition = SearchCond.getAndCond(
-                SearchCond.getLeafCond(groupNameLeafCond),
-                SearchCond.getLeafCond(idRightCond));
-
-        assertTrue(searchCondition.isValid());
-
-        List<Group> matchingGroups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, SubjectType.GROUP);
-
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.size());
-        assertEquals("root", matchingGroups.iterator().next().getName());
-        assertEquals(1L, matchingGroups.iterator().next().getKey(), 0);
-    }
-
-    @Test
-    public void searchByUsernameAndFullname() {
-        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
-        usernameLeafCond.setSchema("username");
-        usernameLeafCond.setExpression("rossini");
-
-        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
-        idRightCond.setSchema("fullname");
-        idRightCond.setExpression("Giuseppe V%");
-
-        SearchCond searchCondition = SearchCond.getOrCond(
-                SearchCond.getLeafCond(usernameLeafCond),
-                SearchCond.getLeafCond(idRightCond));
-
-        List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, SubjectType.USER);
-        assertNotNull(matchingUsers);
-        assertEquals(2, matchingUsers.size());
-    }
-
-    @Test
-    public void searchById() {
-        SubjectCond idLeafCond = new SubjectCond(SubjectCond.Type.LT);
-        idLeafCond.setSchema("id");
-        idLeafCond.setExpression("2");
-
-        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
-        assertTrue(searchCondition.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-        assertEquals(1L, users.iterator().next().getKey(), 0);
-
-        idLeafCond = new SubjectCond(SubjectCond.Type.LT);
-        idLeafCond.setSchema("id");
-        idLeafCond.setExpression("4");
-
-        searchCondition = SearchCond.getNotLeafCond(idLeafCond);
-        assertTrue(searchCondition.isValid());
-
-        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(2, users.size());
-        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
-
-            @Override
-            public boolean evaluate(User user) {
-                return user.getKey() == 4;
-            }
-        }));
-    }
-
-    @Test
-    public void userOrderBy() {
-        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
-        usernameLeafCond.setSchema("username");
-        usernameLeafCond.setExpression("rossini");
-        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
-        idRightCond.setSchema("fullname");
-        idRightCond.setExpression("Giuseppe V%");
-        SearchCond searchCondition = SearchCond.getOrCond(
-                SearchCond.getLeafCond(usernameLeafCond), SearchCond.getLeafCond(idRightCond));
-
-        List<OrderByClause> orderByClauses = new ArrayList<>();
-        OrderByClause orderByClause = new OrderByClause();
-        orderByClause.setField("username");
-        orderByClause.setDirection(OrderByClause.Direction.DESC);
-        orderByClauses.add(orderByClause);
-        orderByClause = new OrderByClause();
-        orderByClause.setField("fullname");
-        orderByClause.setDirection(OrderByClause.Direction.ASC);
-        orderByClauses.add(orderByClause);
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, orderByClauses, SubjectType.USER);
-        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER),
-                users.size());
-    }
-
-    @Test
-    public void groupOrderBy() {
-        SubjectCond idLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
-        idLeafCond.setSchema("name");
-        idLeafCond.setExpression("%r");
-        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
-        assertTrue(searchCondition.isValid());
-
-        OrderByClause orderByClause = new OrderByClause();
-        orderByClause.setField("name");
-
-        List<Group> groups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, Collections.singletonList(orderByClause), SubjectType.GROUP);
-        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
-                searchCondition, SubjectType.GROUP),
-                groups.size());
-    }
-
-    @Test
-    public void issue202() {
-        ResourceCond ws2 = new ResourceCond();
-        ws2.setResourceName("ws-target-resource-2");
-
-        ResourceCond ws1 = new ResourceCond();
-        ws1.setResourceName("ws-target-resource-list-mappings-1");
-
-        SearchCond searchCondition =
-                SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), SearchCond.getNotLeafCond(ws1));
-        assertTrue(searchCondition.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(2, users.size());
-        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
-
-            @Override
-            public boolean evaluate(User user) {
-                return user.getKey() == 4;
-            }
-        }));
-    }
-
-    @Test
-    public void issue242() {
-        SubjectCond cond = new SubjectCond(AttributeCond.Type.LIKE);
-        cond.setSchema("id");
-        cond.setExpression("test%");
-
-        SearchCond searchCondition = SearchCond.getLeafCond(cond);
-        assertTrue(searchCondition.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertTrue(users.isEmpty());
-    }
-
-    @Test
-    public void issueSYNCOPE46() {
-        SubjectCond cond = new SubjectCond(AttributeCond.Type.LIKE);
-        cond.setSchema("username");
-        cond.setExpression("%ossin%");
-
-        SearchCond searchCondition = SearchCond.getLeafCond(cond);
-        assertTrue(searchCondition.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-    }
-
-    @Test
-    public void issueSYNCOPE433() {
-        AttributeCond isNullCond = new AttributeCond(AttributeCond.Type.ISNULL);
-        isNullCond.setSchema("loginDate");
-
-        SubjectCond likeCond = new SubjectCond(AttributeCond.Type.LIKE);
-        likeCond.setSchema("username");
-        likeCond.setExpression("%ossin%");
-
-        SearchCond searchCond = SearchCond.getOrCond(
-                SearchCond.getLeafCond(isNullCond), SearchCond.getLeafCond(likeCond));
-
-        Integer count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCond, SubjectType.USER);
-        assertNotNull(count);
-        assertTrue(count > 0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
index 5fc71d2..43d65d1 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
@@ -26,14 +26,14 @@ import static org.junit.Assert.assertNull;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 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.ExternalResource;
+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.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
@@ -81,12 +81,12 @@ public class TaskTest extends AbstractTest {
 
         PropagationTask task = entityFactory.newEntity(PropagationTask.class);
         task.setResource(resource);
-        task.setSubjectType(AttributableType.USER);
+        task.setAnyTypeKind(AnyTypeKind.USER);
         task.setPropagationMode(PropagationMode.TWO_PHASES);
         task.setPropagationOperation(ResourceOperation.CREATE);
-        task.setAccountId("one@two.com");
+        task.setConnObjectKey("one@two.com");
 
-        Set<Attribute> attributes = new HashSet<Attribute>();
+        Set<Attribute> attributes = new HashSet<>();
         attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
         attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
         task.setAttributes(attributes);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java
index 9537d5e..e1ffc11 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java
@@ -23,19 +23,14 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
@@ -55,9 +50,6 @@ public class VirAttrTest extends AbstractTest {
     private GroupDAO groupDAO;
 
     @Autowired
-    private MembershipDAO membershipDAO;
-
-    @Autowired
     private VirSchemaDAO virSchemaDAO;
 
     @Test
@@ -74,7 +66,7 @@ public class VirAttrTest extends AbstractTest {
 
     @Test
     public void saveUVirAttribute() {
-        UVirSchema virSchema = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        VirSchema virSchema = virSchemaDAO.find("virtualdata");
         assertNotNull(virSchema);
 
         User owner = userDAO.find(3L);
@@ -92,33 +84,18 @@ public class VirAttrTest extends AbstractTest {
     }
 
     @Test
-    public void saveMVirAttribute() {
-        Membership owner = membershipDAO.find(3L);
-        assertNotNull("did not get expected membership", owner);
-
-        MVirAttr virAttr = entityFactory.newEntity(MVirAttr.class);
-        virAttr.setOwner(owner);
-        virAttr.setTemplate(owner.getGroup().getAttrTemplate(MVirAttrTemplate.class, "mvirtualdata"));
-
-        virAttr = virAttrDAO.save(virAttr);
-        assertNotNull(virAttr.getTemplate());
-
-        MVirAttr actual = virAttrDAO.find(virAttr.getKey(), MVirAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(virAttr, actual);
-    }
+    public void saveGVirAttribute() {
+        VirSchema virSchema = virSchemaDAO.find("rvirtualdata");
+        assertNotNull(virSchema);
 
-    @Test
-    public void saveRVirAttribute() {
         Group owner = groupDAO.find(3L);
         assertNotNull("did not get expected membership", owner);
 
         GVirAttr virAttr = entityFactory.newEntity(GVirAttr.class);
         virAttr.setOwner(owner);
-        virAttr.setTemplate(owner.getAttrTemplate(GVirAttrTemplate.class, "rvirtualdata"));
+        virAttr.setSchema(virSchema);
 
         virAttr = virAttrDAO.save(virAttr);
-        assertNotNull(virAttr.getTemplate());
 
         GVirAttr actual = virAttrDAO.find(virAttr.getKey(), GVirAttr.class);
         assertNotNull("expected save to work", actual);
@@ -135,8 +112,7 @@ public class VirAttrTest extends AbstractTest {
         UVirAttr actual = virAttrDAO.find(1000L, UVirAttr.class);
         assertNull("delete did not work", actual);
 
-        UVirSchema attributeSchema = virSchemaDAO.find(attributeSchemaName, UVirSchema.class);
-
+        VirSchema attributeSchema = virSchemaDAO.find(attributeSchemaName);
         assertNotNull("user virtual attribute schema deleted " + "when deleting values", attributeSchema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java
index 919f787..3706f5f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java
@@ -25,13 +25,10 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.List;
-import org.apache.syncope.common.lib.types.AttributableType;
 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.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,51 +42,51 @@ public class VirSchemaTest extends AbstractTest {
 
     @Test
     public void findAll() {
-        List<UVirSchema> list = virSchemaDAO.findAll(UVirSchema.class);
-        assertEquals(2, list.size());
+        List<VirSchema> list = virSchemaDAO.findAll();
+        assertEquals(4, list.size());
     }
 
     @Test
     public void findByName() {
-        UVirSchema attributeSchema = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        VirSchema attributeSchema = virSchemaDAO.find("virtualdata");
         assertNotNull("did not find expected virtual attribute schema", attributeSchema);
     }
 
     @Test
     public void save() {
-        UVirSchema virtualAttributeSchema = entityFactory.newEntity(UVirSchema.class);
+        VirSchema virtualAttributeSchema = entityFactory.newEntity(VirSchema.class);
         virtualAttributeSchema.setKey("virtual");
         virtualAttributeSchema.setReadonly(true);
 
         virSchemaDAO.save(virtualAttributeSchema);
 
-        UVirSchema actual = virSchemaDAO.find("virtual", UVirSchema.class);
+        VirSchema actual = virSchemaDAO.find("virtual");
         assertNotNull("expected save to work", actual);
         assertTrue(actual.isReadonly());
     }
 
     @Test
     public void delete() {
-        UVirSchema virtualdata = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        VirSchema virtualdata = virSchemaDAO.find("virtualdata");
 
-        virSchemaDAO.delete(virtualdata.getKey(), attrUtilsFactory.getInstance(AttributableType.USER));
+        virSchemaDAO.delete(virtualdata.getKey());
 
-        VirSchema actual = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        VirSchema actual = virSchemaDAO.find("virtualdata");
         assertNull("delete did not work", actual);
 
         // ------------- //
-        GVirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata", GVirSchema.class);
+        VirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata");
         assertNotNull(rvirtualdata);
 
-        virSchemaDAO.delete(rvirtualdata.getKey(), attrUtilsFactory.getInstance(AttributableType.GROUP));
+        virSchemaDAO.delete(rvirtualdata.getKey());
 
-        actual = virSchemaDAO.find("rvirtualdata", GVirSchema.class);
+        actual = virSchemaDAO.find("rvirtualdata");
         assertNull("delete did not work", actual);
     }
 
     @Test
     public void issueSYNCOPE418() {
-        UVirSchema schema = entityFactory.newEntity(UVirSchema.class);
+        VirSchema schema = entityFactory.newEntity(VirSchema.class);
         schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnySearchTest.java
new file mode 100644
index 0000000..b038222
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnySearchTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
+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.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnySearchTest extends AbstractTest {
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Test
+    public void issueSYNCOPE95() {
+        Set<Group> groups = new HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
+        for (Group group : groups) {
+            groupDAO.delete(group.getKey());
+        }
+        groupDAO.flush();
+
+        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(4L, users.get(0).getKey(), 0);
+    }
+
+    @Test
+    public void searchByDynMembership() {
+        // 1. create role with dynamic membership
+        Role role = entityFactory.newEntity(Role.class);
+        role.setName("new");
+        role.addRealm(realmDAO.getRoot());
+        role.addRealm(realmDAO.find("/even/two"));
+        role.getEntitlements().add(Entitlement.LOG_LIST);
+        role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
+
+        DynRoleMembership dynMembership = entityFactory.newEntity(DynRoleMembership.class);
+        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setRole(role);
+
+        role.setDynMembership(dynMembership);
+
+        role = roleDAO.save(role);
+        assertNotNull(role);
+
+        roleDAO.flush();
+
+        // 2. search user by this dynamic role
+        RoleCond roleCond = new RoleCond();
+        roleCond.setRoleKey(role.getKey());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(roleCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+        assertEquals(4L, users.get(0).getKey(), 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java
index 6c99465..ef500fe 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java
@@ -25,24 +25,18 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
+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.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -70,12 +64,6 @@ public class AttrTest extends AbstractTest {
     private DerSchemaDAO derSchemaDAO;
 
     @Autowired
-    private MembershipDAO membershipDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
     private UserDAO userDAO;
 
     @Test
@@ -106,48 +94,43 @@ public class AttrTest extends AbstractTest {
     @Test
     public void checkForEnumType() {
         User user = userDAO.find(1L);
-        Membership membership = user.getMembership(1L);
-        assertNotNull(membership);
+        user.setPassword("password123", CipherAlgorithm.SHA);
+        assertNotNull(user);
 
-        MPlainSchema schema = entityFactory.newEntity(MPlainSchema.class);
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setType(AttrSchemaType.Enum);
         schema.setKey("color");
         schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
 
-        MPlainSchema actualSchema = plainSchemaDAO.save(schema);
+        PlainSchema actualSchema = plainSchemaDAO.save(schema);
         assertNotNull(actualSchema);
 
-        MPlainAttrTemplate template = entityFactory.newEntity(MPlainAttrTemplate.class);
-        template.setSchema(actualSchema);
-        membership.getGroup().getAttrTemplates(MPlainAttrTemplate.class).add(template);
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setSchema(actualSchema);
+        attr.setOwner(user);
+        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
 
-        MPlainAttr attr = entityFactory.newEntity(MPlainAttr.class);
-        attr.setTemplate(template);
-        attr.setOwner(membership);
-        attr.addValue("yellow", attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
-        membership.addPlainAttr(attr);
+        userDAO.save(user);
+        userDAO.flush();
 
-        MPlainAttr actualAttribute = userDAO.save(user).getMembership(1L).getPlainAttr("color");
-        assertNotNull(actualAttribute);
-
-        membership = membershipDAO.find(1L);
-        assertNotNull(membership);
-        assertNotNull(membership.getPlainAttr(schema.getKey()));
-        assertNotNull(membership.getPlainAttr(schema.getKey()).getValues());
-
-        assertEquals(membership.getPlainAttr(schema.getKey()).getValues().size(), 1);
+        user = userDAO.find(1L);
+        assertNotNull(user);
+        assertNotNull(user.getPlainAttr(schema.getKey()));
+        assertNotNull(user.getPlainAttr(schema.getKey()).getValues());
+        assertEquals(user.getPlainAttr(schema.getKey()).getValues().size(), 1);
     }
 
     @Test
     public void derAttrFromSpecialAttrs() {
-        UDerSchema sderived = entityFactory.newEntity(UDerSchema.class);
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
         sderived.setKey("sderived");
         sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
 
         sderived = derSchemaDAO.save(sderived);
         derSchemaDAO.flush();
 
-        UDerSchema actual = derSchemaDAO.find("sderived", UDerSchema.class);
+        DerSchema actual = derSchemaDAO.find("sderived");
         assertNotNull("expected save to work", actual);
         assertEquals(sderived, actual);
 
@@ -170,22 +153,4 @@ public class AttrTest extends AbstractTest {
         assertTrue(value.startsWith("vivaldi - 2010-10-20"));
         assertTrue(value.endsWith("[0]"));
     }
-
-    @Test
-    public void unmatchedGroupAttr() {
-        Group group = groupDAO.find(1L);
-        assertNotNull(group);
-
-        assertNotNull(group.getAttrTemplate(GPlainAttrTemplate.class, "icon"));
-        assertNotNull(group.getPlainAttr("icon"));
-
-        assertTrue(group.getAttrTemplates(GPlainAttrTemplate.class).
-                remove(group.getAttrTemplate(GPlainAttrTemplate.class, "icon")));
-
-        group = groupDAO.save(group);
-        groupDAO.flush();
-
-        assertNull(group.getAttrTemplate(GPlainAttrTemplate.class, "icon"));
-        assertNull(group.getPlainAttr("icon"));
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ConnInstanceTest.java
index ce85dc5..34aaef5 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ConnInstanceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.java
index 92b016e..9448886 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.java
@@ -20,12 +20,11 @@ package org.apache.syncope.core.persistence.jpa.relationship;
 
 import static org.junit.Assert.assertNull;
 
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,13 +44,13 @@ public class DerSchemaTest extends AbstractTest {
 
     @Test
     public void test() {
-        UDerSchema schema = derSchemaDAO.find("cn", UDerSchema.class);
+        DerSchema schema = derSchemaDAO.find("cn");
 
-        derSchemaDAO.delete(schema.getKey(), attrUtilsFactory.getInstance(AttributableType.USER));
+        derSchemaDAO.delete(schema.getKey());
 
         derSchemaDAO.flush();
 
-        assertNull(derSchemaDAO.find(schema.getKey(), UDerSchema.class));
+        assertNull(derSchemaDAO.find(schema.getKey()));
         assertNull(derAttrDAO.find(100L, UDerAttr.class));
         assertNull(userDAO.find(3L).getDerAttr(schema.getKey()));
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
index d6d99ce..4767422 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
@@ -32,7 +32,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
@@ -40,16 +40,14 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 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.JPADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -121,7 +119,7 @@ public class GroupTest extends AbstractTest {
         assertEquals(userDAO.findAllGroups(userDAO.find(2L)).size(), 2);
         assertNull(plainAttrDAO.find(700L, GPlainAttr.class));
         assertNull(plainAttrValueDAO.find(41L, GPlainAttrValue.class));
-        assertNotNull(plainSchemaDAO.find("icon", GPlainSchema.class));
+        assertNotNull(plainSchemaDAO.find("icon"));
     }
 
     /**
@@ -131,7 +129,7 @@ public class GroupTest extends AbstractTest {
      */
     private Collection<Group> findDynGroupMemberships(final User user) {
         TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e.group FROM " + JPADynGroupMembership.class.getSimpleName()
+                "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);
 
@@ -146,10 +144,10 @@ public class GroupTest extends AbstractTest {
         user.setRealm(realmDAO.find("/even/two"));
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(plainSchemaDAO.find("cool", UPlainSchema.class));
+        attribute.setSchema(plainSchemaDAO.find("cool"));
         attribute.setOwner(user);
-        attribute.addValue("true", attrUtilsFactory.getInstance(AttributableType.USER));
-        user.addPlainAttr(attribute);
+        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attribute);
 
         user = userDAO.save(user);
         Long newUserKey = user.getKey();
@@ -160,11 +158,11 @@ public class GroupTest extends AbstractTest {
         group.setRealm(realmDAO.getRoot());
         group.setName("new");
 
-        DynGroupMembership dynMembership = entityFactory.newEntity(DynGroupMembership.class);
+        UDynGroupMembership dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
         dynMembership.setFIQLCond("cool==true");
         dynMembership.setGroup(group);
 
-        group.setDynMembership(dynMembership);
+        group.setUDynMembership(dynMembership);
 
         Group actual = groupDAO.save(group);
         assertNotNull(actual);
@@ -174,14 +172,14 @@ public class GroupTest extends AbstractTest {
         // 2. verify that dynamic membership is there
         actual = groupDAO.find(actual.getKey());
         assertNotNull(actual);
-        assertNotNull(actual.getDynMembership());
-        assertNotNull(actual.getDynMembership().getKey());
-        assertEquals(actual, actual.getDynMembership().getGroup());
+        assertNotNull(actual.getUDynMembership());
+        assertNotNull(actual.getUDynMembership().getKey());
+        assertEquals(actual, actual.getUDynMembership().getGroup());
 
         // 3. verify that expected users have the created group dynamically assigned
-        assertEquals(2, actual.getDynMembership().getUsers().size());
+        assertEquals(2, actual.getUDynMembership().getMembers().size());
         assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getDynMembership().getUsers(), new Transformer<User, Long>() {
+                CollectionUtils.collect(actual.getUDynMembership().getMembers(), new Transformer<User, Long>() {
 
                     @Override
                     public Long transform(final User input) {
@@ -193,7 +191,7 @@ public class GroupTest extends AbstractTest {
         assertNotNull(user);
         Collection<Group> dynGroupMemberships = findDynGroupMemberships(user);
         assertEquals(1, dynGroupMemberships.size());
-        assertTrue(dynGroupMemberships.contains(actual.getDynMembership().getGroup()));
+        assertTrue(dynGroupMemberships.contains(actual.getUDynMembership().getGroup()));
 
         // 4. delete the new user and verify that dynamic membership was updated
         userDAO.delete(newUserKey);
@@ -201,17 +199,17 @@ public class GroupTest extends AbstractTest {
         userDAO.flush();
 
         actual = groupDAO.find(actual.getKey());
-        assertEquals(1, actual.getDynMembership().getUsers().size());
-        assertEquals(4L, actual.getDynMembership().getUsers().get(0).getKey(), 0);
+        assertEquals(1, actual.getUDynMembership().getMembers().size());
+        assertEquals(4L, actual.getUDynMembership().getMembers().get(0).getKey(), 0);
 
         // 5. delete group and verify that dynamic membership was also removed
-        Long dynMembershipKey = actual.getDynMembership().getKey();
+        Long dynMembershipKey = actual.getUDynMembership().getKey();
 
         groupDAO.delete(actual);
 
         groupDAO.flush();
 
-        assertNull(entityManager.find(JPADynGroupMembership.class, dynMembershipKey));
+        assertNull(entityManager.find(JPAUDynGroupMembership.class, dynMembershipKey));
 
         dynGroupMemberships = findDynGroupMemberships(user);
         assertTrue(dynGroupMemberships.isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/MembershipTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/MembershipTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/MembershipTest.java
deleted file mode 100644
index 18fa39b..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/MembershipTest.java
+++ /dev/null
@@ -1,81 +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.relationship;
-
-import static org.junit.Assert.assertTrue;
-
-import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class MembershipTest extends AbstractTest {
-
-    @Autowired
-    private MembershipDAO membershipDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Test
-    public void delete() {
-        Membership membership = membershipDAO.find(4L);
-        User user = membership.getUser();
-        Group group = membership.getGroup();
-
-        membershipDAO.delete(4L);
-
-        membershipDAO.flush();
-
-        for (Membership m : user.getMemberships()) {
-            assertTrue(m.getKey() != 4L);
-        }
-        for (Membership m : groupDAO.findMemberships(group)) {
-            assertTrue(m.getKey() != 4L);
-        }
-    }
-
-    @Test
-    public void deleteAndCreate() {
-        Membership membership = membershipDAO.find(3L);
-        User user = membership.getUser();
-        Group group = membership.getGroup();
-
-        // 1. delete that membership
-        membershipDAO.delete(membership.getKey());
-
-        // if not flushing here, the INSERT below will be executed
-        // before the DELETE above
-        membershipDAO.flush();
-
-        // 2. (in the same transaction) create new membership with same user
-        // and group (in order to check the UNIQE constraint on Membership)
-        membership = entityFactory.newEntity(Membership.class);
-        membership.setUser(user);
-        membership.setGroup(group);
-
-        membership = membershipDAO.save(membership);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
index f697692..b92debb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
@@ -26,15 +26,15 @@ import static org.junit.Assert.assertTrue;
 
 import java.util.HashSet;
 import java.util.Set;
-import org.apache.syncope.common.lib.types.AttributableType;
+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.PlainAttrDAO;
 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.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+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.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -44,6 +44,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class PlainSchemaTest extends AbstractTest {
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -57,25 +60,27 @@ public class PlainSchemaTest extends AbstractTest {
 
     @Test
     public void deleteFullname() {
-        // fullname is mapped as AccountId for ws-target-resource-2, need to swap it otherwise validation errors 
+        // fullname is mapped as ConnObjectKey for ws-target-resource-2, need to swap it otherwise validation errors 
         // will be raised
-        for (MappingItem item : resourceDAO.find("ws-target-resource-2").getUmapping().getItems()) {
+        for (MappingItem item : resourceDAO.find("ws-target-resource-2").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+
             if ("fullname".equals(item.getIntAttrName())) {
-                item.setAccountid(false);
+                item.setConnObjectKey(false);
             } else if ("surname".equals(item.getIntAttrName())) {
-                item.setAccountid(true);
+                item.setConnObjectKey(true);
             }
         }
 
         // search for user schema fullname
-        UPlainSchema schema = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        PlainSchema schema = plainSchemaDAO.find("fullname");
         assertNotNull(schema);
 
         // check for associated mappings
         Set<MappingItem> mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getUmapping() != null) {
-                for (MappingItem mapItem : resource.getUmapping().getItems()) {
+            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
                     }
@@ -85,12 +90,12 @@ public class PlainSchemaTest extends AbstractTest {
         assertFalse(mapItems.isEmpty());
 
         // delete user schema fullname
-        plainSchemaDAO.delete("fullname", attrUtilsFactory.getInstance(AttributableType.USER));
+        plainSchemaDAO.delete("fullname");
 
         plainSchemaDAO.flush();
 
         // check for schema deletion
-        schema = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        schema = plainSchemaDAO.find("fullname");
         assertNull(schema);
 
         plainSchemaDAO.clear();
@@ -98,8 +103,8 @@ public class PlainSchemaTest extends AbstractTest {
         // check for mappings deletion
         mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getUmapping() != null) {
-                for (MappingItem mapItem : resource.getUmapping().getItems()) {
+            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if ("fullname".equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
                     }
@@ -117,14 +122,14 @@ public class PlainSchemaTest extends AbstractTest {
     @Test
     public void deleteSurname() {
         // search for user schema fullname
-        UPlainSchema schema = plainSchemaDAO.find("surname", UPlainSchema.class);
+        PlainSchema schema = plainSchemaDAO.find("surname");
         assertNotNull(schema);
 
         // check for associated mappings
         Set<MappingItem> mappings = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getUmapping() != null) {
-                for (MappingItem mapItem : resource.getUmapping().getItems()) {
+            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mappings.add(mapItem);
                     }
@@ -134,24 +139,26 @@ public class PlainSchemaTest extends AbstractTest {
         assertFalse(mappings.isEmpty());
 
         // delete user schema fullname
-        plainSchemaDAO.delete("surname", attrUtilsFactory.getInstance(AttributableType.USER));
+        plainSchemaDAO.delete("surname");
 
         plainSchemaDAO.flush();
 
         // check for schema deletion
-        schema = plainSchemaDAO.find("surname", UPlainSchema.class);
+        schema = plainSchemaDAO.find("surname");
         assertNull(schema);
     }
 
     @Test
     public void deleteALong() {
-        assertEquals(6, resourceDAO.find("resource-db-sync").getUmapping().getItems().size());
+        assertEquals(6, resourceDAO.find("resource-db-sync").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
 
-        plainSchemaDAO.delete("aLong", attrUtilsFactory.getInstance(AttributableType.USER));
-        assertNull(plainSchemaDAO.find("aLong", UPlainSchema.class));
+        plainSchemaDAO.delete("aLong");
+        assertNull(plainSchemaDAO.find("aLong"));
 
         plainSchemaDAO.flush();
 
-        assertEquals(5, resourceDAO.find("resource-db-sync").getUmapping().getItems().size());
+        assertEquals(5, resourceDAO.find("resource-db-sync").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
index 868f104..33e8669 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
@@ -32,21 +32,23 @@ import javax.persistence.EntityManager;
 import org.apache.syncope.common.lib.types.IntMappingType;
 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;
 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.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.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
+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.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 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.group.JPAGMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -64,6 +66,9 @@ public class ResourceTest extends AbstractTest {
     private ConnInstanceDAO connInstanceDAO;
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -109,43 +114,49 @@ public class ResourceTest extends AbstractTest {
 
         resource.setConnector(connector);
 
-        UMapping mapping = entityFactory.newEntity(UMapping.class);
-        mapping.setResource(resource);
-        resource.setUmapping(mapping);
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
 
         // specify mappings
         for (int i = 0; i < 3; i++) {
-            UMappingItem item = entityFactory.newEntity(UMappingItem.class);
+            MappingItem item = entityFactory.newEntity(MappingItem.class);
             item.setExtAttrName("test" + i);
             item.setIntAttrName("nonexistent" + i);
             item.setIntMappingType(IntMappingType.UserPlainSchema);
             item.setMandatoryCondition("false");
             item.setPurpose(MappingPurpose.SYNCHRONIZATION);
-            mapping.addItem(item);
+            mapping.add(item);
             item.setMapping(mapping);
         }
-        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
-        accountId.setExtAttrName("username");
-        accountId.setIntAttrName("username");
-        accountId.setIntMappingType(IntMappingType.UserId);
-        accountId.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.setAccountIdItem(accountId);
-        accountId.setMapping(mapping);
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("username");
+        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.setConnObjectKeyItem(connObjectKey);
+        connObjectKey.setMapping(mapping);
 
         // map a derived attribute
-        UMappingItem derived = entityFactory.newEntity(UMappingItem.class);
-        derived.setAccountid(false);
+        MappingItem derived = entityFactory.newEntity(MappingItem.class);
+        derived.setConnObjectKey(false);
         derived.setExtAttrName("fullname");
         derived.setIntAttrName("cn");
         derived.setIntMappingType(IntMappingType.UserDerivedSchema);
         derived.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.addItem(derived);
+        mapping.add(derived);
         derived.setMapping(mapping);
 
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
         assertNotNull(actual);
-        assertNotNull(actual.getUmapping());
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
 
         resourceDAO.flush();
         resourceDAO.detach(actual);
@@ -155,13 +166,14 @@ public class ResourceTest extends AbstractTest {
         User user = userDAO.find(1L);
         assertNotNull("user not found", user);
 
-        user.addResource(actual);
+        user.add(actual);
 
         resourceDAO.flush();
 
         // retrieve resource
         resource = resourceDAO.find(actual.getKey());
         assertNotNull(resource);
+        resourceDAO.refresh(resource);
 
         // check connector
         connector = connInstanceDAO.find(100L);
@@ -172,7 +184,7 @@ public class ResourceTest extends AbstractTest {
         assertTrue(resource.getConnector().equals(connector));
 
         // check mappings
-        List<? extends UMappingItem> items = resource.getUmapping().getItems();
+        List<? extends MappingItem> items = resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems();
         assertNotNull(items);
         assertEquals(5, items.size());
 
@@ -247,18 +259,18 @@ public class ResourceTest extends AbstractTest {
     public void emptyMapping() {
         ExternalResource ldap = resourceDAO.find("resource-ldap");
         assertNotNull(ldap);
-        assertNotNull(ldap.getUmapping());
-        assertNotNull(ldap.getGmapping());
+        assertNotNull(ldap.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertNotNull(ldap.getProvision(anyTypeDAO.findGroup()).getMapping());
 
-        List<? extends GMappingItem> items = ldap.getGmapping().getItems();
+        List<? extends MappingItem> items = ldap.getProvision(anyTypeDAO.findGroup()).getMapping().getItems();
         assertNotNull(items);
         assertFalse(items.isEmpty());
-        List<Long> itemIds = new ArrayList<>(items.size());
-        for (GMappingItem item : items) {
-            itemIds.add(item.getKey());
+        List<Long> itemKeys = new ArrayList<>(items.size());
+        for (MappingItem item : items) {
+            itemKeys.add(item.getKey());
         }
 
-        ldap.setGmapping(null);
+        ldap.remove(ldap.getProvision(anyTypeDAO.findGroup()));
 
         // need to avoid any class not defined in this Maven module
         ldap.getPropagationActionsClassNames().clear();
@@ -266,8 +278,8 @@ public class ResourceTest extends AbstractTest {
         resourceDAO.save(ldap);
         resourceDAO.flush();
 
-        for (Long itemId : itemIds) {
-            assertNull(entityManager.find(JPAGMappingItem.class, itemId));
+        for (Long itemId : itemKeys) {
+            assertNull(entityManager.find(JPAMappingItem.class, itemId));
         }
     }
 
@@ -276,19 +288,19 @@ public class ResourceTest extends AbstractTest {
         ExternalResource csv = resourceDAO.find("resource-csv");
         assertNotNull(csv);
 
-        int origMapItems = csv.getUmapping().getItems().size();
+        int origMapItems = csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size();
 
-        UMappingItem newMapItem = entityFactory.newEntity(UMappingItem.class);
+        MappingItem newMapItem = entityFactory.newEntity(MappingItem.class);
         newMapItem.setIntMappingType(IntMappingType.Username);
         newMapItem.setExtAttrName("TEST");
         newMapItem.setPurpose(MappingPurpose.PROPAGATION);
-        csv.getUmapping().addItem(newMapItem);
+        csv.getProvision(anyTypeDAO.findUser()).getMapping().add(newMapItem);
 
         resourceDAO.save(csv);
         resourceDAO.flush();
 
         csv = resourceDAO.find("resource-csv");
         assertNotNull(csv);
-        assertEquals(origMapItems + 1, csv.getUmapping().getItems().size());
+        assertEquals(origMapItems + 1, csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
index 52e3451..5f2504b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
@@ -30,19 +30,18 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 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.JPADynRoleMembership;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -87,10 +86,10 @@ public class RoleTest extends AbstractTest {
         user.setRealm(realmDAO.find("/even/two"));
 
         UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(plainSchemaDAO.find("cool", UPlainSchema.class));
+        attribute.setSchema(plainSchemaDAO.find("cool"));
         attribute.setOwner(user);
-        attribute.addValue("true", attrUtilsFactory.getInstance(AttributableType.USER));
-        user.addPlainAttr(attribute);
+        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attribute);
 
         user = userDAO.save(user);
         Long newUserKey = user.getKey();
@@ -123,9 +122,9 @@ public class RoleTest extends AbstractTest {
         assertEquals(actual, actual.getDynMembership().getRole());
 
         // 3. verify that expected users have the created role dynamically assigned
-        assertEquals(2, actual.getDynMembership().getUsers().size());
+        assertEquals(2, actual.getDynMembership().getMembers().size());
         assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getDynMembership().getUsers(), new Transformer<User, Long>() {
+                CollectionUtils.collect(actual.getDynMembership().getMembers(), new Transformer<User, Long>() {
 
                     @Override
                     public Long transform(final User input) {
@@ -145,8 +144,8 @@ public class RoleTest extends AbstractTest {
         userDAO.flush();
 
         actual = roleDAO.find(actual.getKey());
-        assertEquals(1, actual.getDynMembership().getUsers().size());
-        assertEquals(4L, actual.getDynMembership().getUsers().get(0).getKey(), 0);
+        assertEquals(1, actual.getDynMembership().getMembers().size());
+        assertEquals(4L, actual.getDynMembership().getMembers().get(0).getKey(), 0);
 
         // 5. delete role and verify that dynamic membership was also removed
         Long dynMembershipKey = actual.getDynMembership().getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
deleted file mode 100644
index 025d7cc..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
+++ /dev/null
@@ -1,115 +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.relationship;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
-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.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class SubjectSearchTest extends AbstractTest {
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private SubjectSearchDAO searchDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Test
-    public void issueSYNCOPE95() {
-        Set<Group> groups = new HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
-        for (Group group : groups) {
-            groupDAO.delete(group.getKey());
-        }
-        groupDAO.flush();
-
-        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
-        coolLeafCond.setSchema("cool");
-        coolLeafCond.setExpression("true");
-
-        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
-        assertTrue(cond.isValid());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-
-        assertEquals(4L, users.get(0).getKey(), 0);
-    }
-
-    @Test
-    public void searchByDynMembership() {
-        // 1. create role with dynamic membership
-        Role role = entityFactory.newEntity(Role.class);
-        role.setName("new");
-        role.addRealm(realmDAO.getRoot());
-        role.addRealm(realmDAO.find("/even/two"));
-        role.getEntitlements().add(Entitlement.LOG_LIST);
-        role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
-
-        DynRoleMembership dynMembership = entityFactory.newEntity(DynRoleMembership.class);
-        dynMembership.setFIQLCond("cool==true");
-        dynMembership.setRole(role);
-
-        role.setDynMembership(dynMembership);
-
-        role = roleDAO.save(role);
-        assertNotNull(role);
-
-        roleDAO.flush();
-
-        // 2. search user by this dynamic role
-        RoleCond roleCond = new RoleCond();
-        roleCond.setRoleKey(role.getKey());
-
-        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                SearchCond.getLeafCond(roleCond), SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-        assertEquals(4L, users.get(0).getKey(), 0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java
index e795a95..76621a1 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java
@@ -28,7 +28,7 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
 import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
@@ -40,11 +40,12 @@ 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.TaskExecDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+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.PushTask;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
@@ -89,10 +90,10 @@ public class TaskTest extends AbstractTest {
 
         PropagationTask task = entityFactory.newEntity(PropagationTask.class);
         task.setResource(resource);
-        task.setSubjectType(AttributableType.USER);
+        task.setAnyTypeKind(AnyTypeKind.USER);
         task.setPropagationMode(PropagationMode.TWO_PHASES);
         task.setPropagationOperation(ResourceOperation.CREATE);
-        task.setAccountId("one@two.com");
+        task.setConnObjectKey("one@two.com");
 
         Set<Attribute> attributes = new HashSet<>();
         attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
@@ -207,10 +208,13 @@ public class TaskTest extends AbstractTest {
         ExternalResource resource = resourceDAO.find("ws-target-resource-1");
         assertNotNull(resource);
 
+        AnyTemplate template = entityFactory.newEntity(AnyTemplate.class);
+        template.set(new UserTO());
+
         SyncTask task = entityFactory.newEntity(SyncTask.class);
         task.setName("saveSyncTask");
         task.setDescription("SyncTask description");
-        task.setUserTemplate(new UserTO());
+        task.add(template);
         task.setCronExpression("BLA BLA");
         task.setMatchingRule(MatchingRule.UPDATE);
         task.setUnmatchingRule(UnmatchingRule.PROVISION);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java
index ccfa33d..f038917 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java
@@ -28,10 +28,9 @@ import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -64,9 +63,9 @@ public class UserTest extends AbstractTest {
         assertNull(userDAO.find(4L));
         assertNull(plainAttrDAO.find(550L, UPlainAttr.class));
         assertNull(plainAttrValueDAO.find(22L, UPlainAttrValue.class));
-        assertNotNull(plainSchemaDAO.find("loginDate", UPlainSchema.class));
+        assertNotNull(plainSchemaDAO.find("loginDate"));
 
-        List<Membership> memberships = groupDAO.findMemberships(groupDAO.find(7L));
+        List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L));
         assertTrue(memberships.isEmpty());
     }
 }


[21/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java
new file mode 100644
index 0000000..5b253d8
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java
@@ -0,0 +1,29 @@
+/*
+ * 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.user;
+
+import org.apache.syncope.core.persistence.api.entity.DynMembership;
+import org.apache.syncope.core.persistence.api.entity.Role;
+
+public interface DynRoleMembership extends DynMembership<User> {
+
+    Role getRole();
+
+    void setRole(Role role);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java
index 9c88907..b3ebdec 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java
@@ -20,12 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.user;
 
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 
-public interface UDerAttr extends DerAttr {
-
-    @Override
-    User getOwner();
-
-    @Override
-    UDerSchema getSchema();
+public interface UDerAttr extends DerAttr<User> {
 
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java
new file mode 100644
index 0000000..efec3f1
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java
@@ -0,0 +1,25 @@
+/*
+ * 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.user;
+
+import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
+
+public interface UDynGroupMembership extends DynGroupMembership<User> {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java
new file mode 100644
index 0000000..7901a6e
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java
@@ -0,0 +1,25 @@
+/*
+ * 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.user;
+
+import org.apache.syncope.core.persistence.api.entity.DynMembership;
+
+public interface UDynMembership extends DynMembership<User> {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java
deleted file mode 100644
index f99b4bc..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.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.user;
-
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-
-public interface UMapping extends Mapping<UMappingItem> {
-
-    UMappingItem getPasswordItem();
-
-    boolean setPasswordItem(UMappingItem item);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java
deleted file mode 100644
index a21aa0a..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java
+++ /dev/null
@@ -1,29 +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.user;
-
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-
-public interface UMappingItem extends MappingItem {
-
-    @Override
-    Mapping<UMappingItem> getMapping();
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java
new file mode 100644
index 0000000..76f9ef6
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java
@@ -0,0 +1,25 @@
+/*
+ * 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.user;
+
+import org.apache.syncope.core.persistence.api.entity.Membership;
+
+public interface UMembership extends Membership<User> {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java
index fa861d9..5c91acf 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java
@@ -21,13 +21,7 @@ package org.apache.syncope.core.persistence.api.entity.user;
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 
-public interface UPlainAttr extends PlainAttr {
-
-    @Override
-    User getOwner();
-
-    @Override
-    UPlainSchema getSchema();
+public interface UPlainAttr extends PlainAttr<User> {
 
     @Override
     List<? extends UPlainAttrValue> getValues();

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java
index db3ff47..71eb24e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java
@@ -25,7 +25,4 @@ public interface UPlainAttrUniqueValue extends PlainAttrUniqueValue {
     @Override
     UPlainAttr getAttr();
 
-    @Override
-    UPlainSchema getSchema();
-
 }

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java
index 12f1b5e..bb3ab70 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java
@@ -20,12 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.user;
 
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 
-public interface UVirAttr extends VirAttr {
-
-    @Override
-    User getOwner();
-
-    @Override
-    UVirSchema getSchema();
+public interface UVirAttr extends VirAttr<User> {
 
 }

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
index 7349ecb..d896984 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
@@ -18,129 +18,104 @@
  */
 package org.apache.syncope.core.persistence.api.entity.user;
 
-import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 
-public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
+public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> {
 
-    boolean addRole(Role role);
+    String getUsername();
 
-    boolean addMembership(Membership membership);
+    void setUsername(String username);
 
-    boolean canDecodePassword();
+    String getToken();
 
-    boolean checkToken(String token);
+    Date getTokenExpireTime();
 
     void generateToken(int tokenLength, int tokenExpireTime);
 
-    Date getChangePwdDate();
-
-    CipherAlgorithm getCipherAlgorithm();
-
-    String getClearPassword();
-
-    Integer getFailedLogins();
-
-    Date getLastLoginDate();
-
-    List<? extends Role> getRoles();
-
-    Membership getMembership(Long groupKey);
-
-    List<? extends Membership> getMemberships();
-
-    Collection<Long> getStaticGroupKeys();
-
-    String getPassword();
-
-    List<String> getPasswordHistory();
-
-    String getSecurityAnswer();
+    void removeToken();
 
-    SecurityQuestion getSecurityQuestion();
+    boolean checkToken(String token);
 
-    String getStatus();
+    boolean hasTokenExpired();
 
-    String getToken();
+    Date getChangePwdDate();
 
-    Date getTokenExpireTime();
+    void setChangePwdDate(Date changePwdDate);
 
-    String getUsername();
+    CipherAlgorithm getCipherAlgorithm();
 
-    String getWorkflowId();
+    void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm);
 
-    boolean hasTokenExpired();
+    boolean canDecodePassword();
 
-    Boolean isSuspended();
+    String getClearPassword();
 
     void removeClearPassword();
 
-    boolean removeRole(Role role);
-
-    boolean removeMembership(Membership membership);
+    String getPassword();
 
-    void removeToken();
+    void setEncodedPassword(String password, CipherAlgorithm cipherAlgoritm);
 
-    void setChangePwdDate(Date changePwdDate);
+    void setPassword(String password, CipherAlgorithm cipherAlgoritm);
 
-    void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm);
+    List<String> getPasswordHistory();
 
-    void setEncodedPassword(String password, CipherAlgorithm cipherAlgoritm);
+    boolean verifyPasswordHistory(String password, int size);
 
-    void setFailedLogins(Integer failedLogins);
+    SecurityQuestion getSecurityQuestion();
 
-    void setLastLoginDate(Date lastLoginDate);
+    void setSecurityQuestion(SecurityQuestion securityQuestion);
 
-    void setPassword(String password, CipherAlgorithm cipherAlgoritm);
+    String getSecurityAnswer();
 
     void setSecurityAnswer(String securityAnswer);
 
-    void setSecurityQuestion(SecurityQuestion securityQuestion);
+    Integer getFailedLogins();
 
-    void setStatus(String status);
+    void setFailedLogins(Integer failedLogins);
 
-    void setSuspended(Boolean suspended);
+    Date getLastLoginDate();
 
-    void setUsername(String username);
+    void setLastLoginDate(Date lastLoginDate);
 
-    void setWorkflowId(String workflowId);
+    Boolean isSuspended();
 
-    boolean verifyPasswordHistory(String password, int size);
+    void setSuspended(Boolean suspended);
 
     @Override
-    boolean addPlainAttr(UPlainAttr attr);
+    boolean add(UPlainAttr attr);
 
     @Override
-    boolean removePlainAttr(UPlainAttr attr);
+    boolean remove(UPlainAttr attr);
 
     @Override
-    boolean addDerAttr(UDerAttr attr);
+    UPlainAttr getPlainAttr(String plainSchemaName);
 
     @Override
-    boolean removeDerAttr(UDerAttr derAttr);
+    List<? extends UPlainAttr> getPlainAttrs();
 
     @Override
-    boolean addVirAttr(UVirAttr attr);
+    boolean add(UDerAttr attr);
 
     @Override
-    boolean removeVirAttr(UVirAttr virAttr);
+    boolean remove(UDerAttr derAttr);
 
     @Override
-    UPlainAttr getPlainAttr(String plainSchemaName);
+    UDerAttr getDerAttr(String derSchemaName);
 
     @Override
-    List<? extends UPlainAttr> getPlainAttrs();
+    List<? extends UDerAttr> getDerAttrs();
 
     @Override
-    UDerAttr getDerAttr(String derSchemaName);
+    boolean add(UVirAttr attr);
 
     @Override
-    List<? extends UDerAttr> getDerAttrs();
+    boolean remove(UVirAttr virAttr);
 
     @Override
     UVirAttr getVirAttr(String virSchemaName);
@@ -148,4 +123,25 @@ public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
     @Override
     List<? extends UVirAttr> getVirAttrs();
 
+    boolean add(Role role);
+
+    boolean remove(Role role);
+
+    List<? extends Role> getRoles();
+
+    boolean add(URelationship relationship);
+
+    boolean remove(URelationship relationship);
+
+    URelationship getRelationship(AnyObject rightEnd);
+
+    List<? extends URelationship> getRelationships();
+
+    boolean add(UMembership membership);
+
+    boolean remove(UMembership membership);
+
+    UMembership getMembership(Long groupKey);
+
+    List<? extends UMembership> getMemberships();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index bc5f6e3..ea13072 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -52,17 +52,21 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.misc.DataFormat;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskExec;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.springframework.jdbc.datasource.DataSourceUtils;
@@ -82,8 +86,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
                 "QRTZ_", "LOGGING", JPAReportExec.TABLE, JPATaskExec.TABLE,
                 JPAUser.TABLE, JPAUPlainAttr.TABLE, JPAUPlainAttrValue.TABLE, JPAUPlainAttrUniqueValue.TABLE,
                 JPAUDerAttr.TABLE, JPAUVirAttr.TABLE,
-                JPAMembership.TABLE, JPAMPlainAttr.TABLE, JPAMPlainAttrValue.TABLE, JPAMPlainAttrUniqueValue.TABLE,
-                JPAMDerAttr.TABLE, JPAMVirAttr.TABLE
+                JPAAnyObject.TABLE, JPAAPlainAttr.TABLE, JPAAPlainAttrValue.TABLE, JPAAPlainAttrUniqueValue.TABLE,
+                JPAADerAttr.TABLE, JPAAVirAttr.TABLE,
+                JPAARelationship.TABLE, JPAAMembership.TABLE, JPAURelationship.TABLE, JPAUMembership.TABLE
             }));
 
     protected static final Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..3448737
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -0,0 +1,434 @@
+/*
+ * 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.dao;
+
+import static org.apache.syncope.core.persistence.jpa.dao.AbstractDAO.LOG;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import org.apache.commons.jexl2.parser.Parser;
+import org.apache.commons.jexl2.parser.ParserConstants;
+import org.apache.commons.jexl2.parser.Token;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+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.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+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.VirAttr;
+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.AbstractPlainAttrValue;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO<A, Long> implements AnyDAO<A> {
+
+    @Autowired
+    protected PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    protected DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    protected AnySearchDAO searchDAO;
+
+    protected AnyUtils anyUtils;
+
+    protected abstract AnyUtils init();
+
+    protected AnyUtils getAnyUtils() {
+        synchronized (this) {
+            if (anyUtils == null) {
+                anyUtils = init();
+            }
+        }
+        return anyUtils;
+    }
+
+    protected abstract void securityChecks(A any);
+
+    @Override
+    public A authFind(final Long key) {
+        if (key == null) {
+            throw new NotFoundException("Null key");
+        }
+
+        A any = find(key);
+        if (any == null) {
+            throw new NotFoundException("Any " + key);
+        }
+
+        securityChecks(any);
+
+        return any;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public A find(final Long key) {
+        return (A) entityManager.find(getAnyUtils().anyClass(), key);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public A findByWorkflowId(final String workflowId) {
+        Query query = entityManager.createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName()
+                + " e WHERE e.workflowId = :workflowId", User.class);
+        query.setParameter("workflowId", workflowId);
+
+        A result = null;
+        try {
+            result = (A) query.getSingleResult();
+        } catch (NoResultException e) {
+            LOG.debug("No user found with workflow id {}", workflowId, e);
+        }
+
+        return result;
+    }
+
+    private Query findByAttrValueQuery(final String entityName) {
+        return entityManager.createQuery("SELECT e FROM " + entityName + " e"
+                + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
+                + " AND e.stringValue = :stringValue)"
+                + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)"
+                + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)"
+                + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)"
+                + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)");
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<A> findByAttrValue(final String schemaName, final PlainAttrValue attrValue) {
+        PlainSchema schema = plainSchemaDAO.find(schemaName);
+        if (schema == null) {
+            LOG.error("Invalid schema name '{}'", schemaName);
+            return Collections.<A>emptyList();
+        }
+
+        String entityName = schema.isUniqueConstraint()
+                ? getAnyUtils().plainAttrUniqueValueClass().getName()
+                : getAnyUtils().plainAttrValueClass().getName();
+        Query query = findByAttrValueQuery(entityName);
+        query.setParameter("schemaName", schemaName);
+        query.setParameter("stringValue", attrValue.getStringValue());
+        query.setParameter("booleanValue", attrValue.getBooleanValue() == null
+                ? null
+                : ((AbstractPlainAttrValue) attrValue).getBooleanAsInteger(attrValue.getBooleanValue()));
+        if (attrValue.getDateValue() == null) {
+            query.setParameter("dateValue", null);
+        } else {
+            query.setParameter("dateValue", attrValue.getDateValue(), TemporalType.TIMESTAMP);
+        }
+        query.setParameter("longValue", attrValue.getLongValue());
+        query.setParameter("doubleValue", attrValue.getDoubleValue());
+
+        List<A> result = new ArrayList<>();
+        for (PlainAttrValue value : (List<PlainAttrValue>) query.getResultList()) {
+            A any = (A) value.getAttr().getOwner();
+            if (!result.contains(any)) {
+                result.add(any);
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public A findByAttrUniqueValue(final String schemaName, final PlainAttrValue attrUniqueValue) {
+        PlainSchema schema = plainSchemaDAO.find(schemaName);
+        if (schema == null) {
+            LOG.error("Invalid schema name '{}'", schemaName);
+            return null;
+        }
+        if (!schema.isUniqueConstraint()) {
+            LOG.error("This schema has not unique constraint: '{}'", schemaName);
+            return null;
+        }
+
+        List<A> result = findByAttrValue(schemaName, attrUniqueValue);
+        return result.isEmpty()
+                ? null
+                : result.iterator().next();
+    }
+
+    /**
+     * Split an attribute value recurring on provided literals/tokens.
+     *
+     * @param attrValue value to be split
+     * @param literals literals/tokens
+     * @return split value
+     */
+    private List<String> split(final String attrValue, final List<String> literals) {
+        final List<String> attrValues = new ArrayList<>();
+
+        if (literals.isEmpty()) {
+            attrValues.add(attrValue);
+        } else {
+            for (String token : attrValue.split(Pattern.quote(literals.get(0)))) {
+                attrValues.addAll(split(token, literals.subList(1, literals.size())));
+            }
+        }
+
+        return attrValues;
+    }
+
+    /**
+     * Generate one where clause for each different attribute schema into the derived schema expression provided.
+     *
+     * @param expression derived schema expression
+     * @param value derived attribute value
+     * @param attrUtils USER / GROUP
+     * @return where clauses to use to build the query
+     */
+    private Set<String> getWhereClause(final String expression, final String value) {
+        final Parser parser = new Parser(new StringReader(expression));
+
+        // Schema names
+        final List<String> identifiers = new ArrayList<>();
+
+        // Literals
+        final List<String> literals = new ArrayList<>();
+
+        // Get schema names and literals
+        for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString());
+                token = parser.getNextToken()) {
+
+            if (token.kind == ParserConstants.STRING_LITERAL) {
+                literals.add(token.toString().substring(1, token.toString().length() - 1));
+            }
+
+            if (token.kind == ParserConstants.IDENTIFIER) {
+                identifiers.add(token.toString());
+            }
+        }
+
+        // Sort literals in order to process later literals included into others
+        Collections.sort(literals, new Comparator<String>() {
+
+            @Override
+            public int compare(final String t, final String t1) {
+                if (t == null && t1 == null) {
+                    return 0;
+                } else if (t != null && t1 == null) {
+                    return -1;
+                } else if (t == null && t1 != null) {
+                    return 1;
+                } else if (t.length() == t1.length()) {
+                    return 0;
+                } else if (t.length() > t1.length()) {
+                    return -1;
+                } else {
+                    return 1;
+                }
+            }
+        });
+
+        // Split value on provided literals
+        final List<String> attrValues = split(value, literals);
+
+        if (attrValues.size() != identifiers.size()) {
+            LOG.error("Ambiguous JEXL expression resolution.");
+            throw new IllegalArgumentException("literals and values have different size");
+        }
+
+        // clauses to be used with INTERSECTed queries
+        final Set<String> clauses = new HashSet<>();
+
+        // builder to build the clauses
+        final StringBuilder bld = new StringBuilder();
+
+        // Contains used identifiers in order to avoid replications
+        final Set<String> used = new HashSet<>();
+
+        // Create several clauses: one for eanch identifiers
+        for (int i = 0; i < identifiers.size(); i++) {
+            if (!used.contains(identifiers.get(i))) {
+
+                // verify schema existence and get schema type
+                PlainSchema schema = plainSchemaDAO.find(identifiers.get(i));
+                if (schema == null) {
+                    LOG.error("Invalid schema name '{}'", identifiers.get(i));
+                    throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i));
+                }
+
+                // clear builder
+                bld.delete(0, bld.length());
+
+                bld.append("(");
+
+                // set schema name
+                bld.append("s.name = '").append(identifiers.get(i)).append("'");
+
+                bld.append(" AND ");
+
+                bld.append("s.name = a.schema_name").append(" AND ");
+
+                bld.append("a.id = v.attribute_id");
+
+                bld.append(" AND ");
+
+                // use a value clause different for eanch different schema type
+                switch (schema.getType()) {
+                    case Boolean:
+                        bld.append("v.booleanValue = '").append(attrValues.get(i)).append("'");
+                        break;
+                    case Long:
+                        bld.append("v.longValue = ").append(attrValues.get(i));
+                        break;
+                    case Double:
+                        bld.append("v.doubleValue = ").append(attrValues.get(i));
+                        break;
+                    case Date:
+                        bld.append("v.dateValue = '").append(attrValues.get(i)).append("'");
+                        break;
+                    default:
+                        bld.append("v.stringValue = '").append(attrValues.get(i)).append("'");
+                }
+
+                bld.append(")");
+
+                used.add(identifiers.get(i));
+
+                clauses.add(bld.toString());
+            }
+        }
+
+        LOG.debug("Generated where clauses {}", clauses);
+
+        return clauses;
+    }
+
+    @Override
+    public List<A> findByDerAttrValue(final String schemaName, final String value) {
+        DerSchema schema = derSchemaDAO.find(schemaName);
+        if (schema == null) {
+            LOG.error("Invalid schema name '{}'", schemaName);
+            return Collections.<A>emptyList();
+        }
+
+        // query string
+        StringBuilder querystring = new StringBuilder();
+
+        boolean subquery = false;
+        for (String clause : getWhereClause(schema.getExpression(), value)) {
+            if (querystring.length() > 0) {
+                subquery = true;
+                querystring.append(" AND a.owner_id IN ( ");
+            }
+
+            querystring.append("SELECT a.owner_id ").
+                    append("FROM ").append(getAnyUtils().plainAttrClass().getSimpleName().substring(3)).append(" a, ").
+                    append(getAnyUtils().plainAttrValueClass().getSimpleName().substring(3)).append(" v, ").
+                    append(PlainSchema.class.getSimpleName()).append(" s ").
+                    append("WHERE ").append(clause);
+
+            if (subquery) {
+                querystring.append(')');
+            }
+        }
+
+        Query query = entityManager.createNativeQuery(querystring.toString());
+
+        List<A> result = new ArrayList<>();
+        for (Object anyKey : query.getResultList()) {
+            A any = find(Long.parseLong(anyKey.toString()));
+            if (!result.contains(any)) {
+                result.add(any);
+            }
+        }
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<A> findByResource(final ExternalResource resource) {
+        Query query = entityManager.createQuery(
+                "SELECT e FROM " + getAnyUtils().anyClass().getSimpleName() + " e "
+                + "WHERE :resource MEMBER OF e.resources");
+        query.setParameter("resource", resource);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public final List<A> findAll(final Set<String> adminRealms,
+            final int page, final int itemsPerPage) {
+
+        return findAll(adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList());
+    }
+
+    private SearchCond getAllMatchingCond() {
+        AnyCond idCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
+        idCond.setSchema("id");
+        return SearchCond.getLeafCond(idCond);
+    }
+
+    @Override
+    public List<A> findAll(final Set<String> adminRealms,
+            final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
+
+        return searchDAO.search(adminRealms, getAllMatchingCond(), page, itemsPerPage, orderBy,
+                getAnyUtils().getAnyTypeKind());
+    }
+
+    @Override
+    public final int count(final Set<String> adminRealms) {
+        return searchDAO.count(adminRealms, getAllMatchingCond(), getAnyUtils().getAnyTypeKind());
+    }
+
+    @Override
+    public A save(final A any) {
+        A merged = entityManager.merge(any);
+        for (VirAttr<?> virAttr : merged.getVirAttrs()) {
+            virAttr.getValues().clear();
+            virAttr.getValues().addAll(any.getVirAttr(virAttr.getSchema().getKey()).getValues());
+        }
+
+        return merged;
+    }
+
+    @Override
+    public void delete(final Long key) {
+        A any = find(key);
+        if (any == null) {
+            return;
+        }
+
+        delete(any);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
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 2bf2b80..a4ff529 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
@@ -37,9 +37,6 @@ import org.springframework.util.ReflectionUtils;
 @Configurable
 public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E, KEY> {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
 
     private static final String CACHE_STORE_MODE = "javax.persistence.cache.storeMode";

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
deleted file mode 100644
index 954651a..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
+++ /dev/null
@@ -1,361 +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.dao;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-import javax.persistence.Query;
-import javax.persistence.TemporalType;
-import org.apache.commons.jexl2.parser.Parser;
-import org.apache.commons.jexl2.parser.ParserConstants;
-import org.apache.commons.jexl2.parser.Token;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
-import org.springframework.beans.factory.annotation.Autowired;
-
-abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V extends VirAttr>
-        extends AbstractDAO<Subject<P, D, V>, Long> implements SubjectDAO<P, D, V> {
-
-    @Autowired
-    protected PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    protected DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    protected SubjectSearchDAO searchDAO;
-
-    protected SearchCond getAllMatchingCond() {
-        SubjectCond idCond = new SubjectCond(AttributeCond.Type.ISNOTNULL);
-        idCond.setSchema("id");
-        return SearchCond.getLeafCond(idCond);
-    }
-
-    /**
-     * Split an attribute value recurring on provided literals/tokens.
-     *
-     * @param attrValue value to be split
-     * @param literals literals/tokens
-     * @return split value
-     */
-    private List<String> split(final String attrValue, final List<String> literals) {
-        final List<String> attrValues = new ArrayList<>();
-
-        if (literals.isEmpty()) {
-            attrValues.add(attrValue);
-        } else {
-            for (String token : attrValue.split(Pattern.quote(literals.get(0)))) {
-                attrValues.addAll(split(token, literals.subList(1, literals.size())));
-            }
-        }
-
-        return attrValues;
-    }
-
-    /**
-     * Generate one where clause for each different attribute schema into the derived schema expression provided.
-     *
-     * @param expression derived schema expression
-     * @param value derived attribute value
-     * @param attrUtils USER / GROUP
-     * @return where clauses to use to build the query
-     */
-    private Set<String> getWhereClause(final String expression, final String value, final AttributableUtils attrUtils) {
-        final Parser parser = new Parser(new StringReader(expression));
-
-        // Schema names
-        final List<String> identifiers = new ArrayList<>();
-
-        // Literals
-        final List<String> literals = new ArrayList<>();
-
-        // Get schema names and literals
-        for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString());
-                token = parser.getNextToken()) {
-
-            if (token.kind == ParserConstants.STRING_LITERAL) {
-                literals.add(token.toString().substring(1, token.toString().length() - 1));
-            }
-
-            if (token.kind == ParserConstants.IDENTIFIER) {
-                identifiers.add(token.toString());
-            }
-        }
-
-        // Sort literals in order to process later literals included into others
-        Collections.sort(literals, new Comparator<String>() {
-
-            @Override
-            public int compare(final String t, final String t1) {
-                if (t == null && t1 == null) {
-                    return 0;
-                } else if (t != null && t1 == null) {
-                    return -1;
-                } else if (t == null && t1 != null) {
-                    return 1;
-                } else if (t.length() == t1.length()) {
-                    return 0;
-                } else if (t.length() > t1.length()) {
-                    return -1;
-                } else {
-                    return 1;
-                }
-            }
-        });
-
-        // Split value on provided literals
-        final List<String> attrValues = split(value, literals);
-
-        if (attrValues.size() != identifiers.size()) {
-            LOG.error("Ambiguous JEXL expression resolution.");
-            throw new IllegalArgumentException("literals and values have different size");
-        }
-
-        // clauses to be used with INTERSECTed queries
-        final Set<String> clauses = new HashSet<>();
-
-        // builder to build the clauses
-        final StringBuilder bld = new StringBuilder();
-
-        // Contains used identifiers in order to avoid replications
-        final Set<String> used = new HashSet<>();
-
-        // Create several clauses: one for eanch identifiers
-        for (int i = 0; i < identifiers.size(); i++) {
-            if (!used.contains(identifiers.get(i))) {
-
-                // verify schema existence and get schema type
-                PlainSchema schema = plainSchemaDAO.find(identifiers.get(i), attrUtils.plainSchemaClass());
-                if (schema == null) {
-                    LOG.error("Invalid schema name '{}'", identifiers.get(i));
-                    throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i));
-                }
-
-                // clear builder
-                bld.delete(0, bld.length());
-
-                bld.append("(");
-
-                // set schema name
-                bld.append("s.name = '").append(identifiers.get(i)).append("'");
-
-                bld.append(" AND ");
-
-                bld.append("s.name = a.schema_name").append(" AND ");
-
-                bld.append("a.id = v.attribute_id");
-
-                bld.append(" AND ");
-
-                // use a value clause different for eanch different schema type
-                switch (schema.getType()) {
-                    case Boolean:
-                        bld.append("v.booleanValue = '").append(attrValues.get(i)).append("'");
-                        break;
-                    case Long:
-                        bld.append("v.longValue = ").append(attrValues.get(i));
-                        break;
-                    case Double:
-                        bld.append("v.doubleValue = ").append(attrValues.get(i));
-                        break;
-                    case Date:
-                        bld.append("v.dateValue = '").append(attrValues.get(i)).append("'");
-                        break;
-                    default:
-                        bld.append("v.stringValue = '").append(attrValues.get(i)).append("'");
-                }
-
-                bld.append(")");
-
-                used.add(identifiers.get(i));
-
-                clauses.add(bld.toString());
-            }
-        }
-
-        LOG.debug("Generated where clauses {}", clauses);
-
-        return clauses;
-    }
-
-    protected abstract Subject<P, D, V> findInternal(Long key);
-
-    private Query findByAttrValueQuery(final String entityName) {
-        return entityManager.createQuery("SELECT e FROM " + entityName + " e"
-                + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
-                + " AND e.stringValue = :stringValue)"
-                + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)"
-                + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)"
-                + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)"
-                + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)");
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<? extends Subject<P, D, V>> findByAttrValue(
-            final String schemaName, final PlainAttrValue attrValue, final AttributableUtils attrUtils) {
-
-        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
-        if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaName);
-            return Collections.<Subject<P, D, V>>emptyList();
-        }
-
-        final String entityName = schema.isUniqueConstraint()
-                ? attrUtils.plainAttrUniqueValueClass().getName()
-                : attrUtils.plainAttrValueClass().getName();
-
-        Query query = findByAttrValueQuery(entityName);
-
-        query.setParameter("schemaName", schemaName);
-        query.setParameter("stringValue", attrValue.getStringValue());
-        query.setParameter("booleanValue", attrValue.getBooleanValue() == null
-                ? null
-                : ((AbstractPlainAttrValue) attrValue).getBooleanAsInteger(attrValue.getBooleanValue()));
-        if (attrValue.getDateValue() == null) {
-            query.setParameter("dateValue", null);
-        } else {
-            query.setParameter("dateValue", attrValue.getDateValue(), TemporalType.TIMESTAMP);
-        }
-        query.setParameter("longValue", attrValue.getLongValue());
-        query.setParameter("doubleValue", attrValue.getDoubleValue());
-
-        List<Subject<P, D, V>> result = new ArrayList<>();
-        for (PlainAttrValue value : (List<PlainAttrValue>) query.getResultList()) {
-            Subject<P, D, V> subject = (Subject<P, D, V>) value.getAttr().getOwner();
-            if (!result.contains(subject)) {
-                result.add(subject);
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public Subject<P, D, V> findByAttrUniqueValue(
-            final String schemaName, final PlainAttrValue attrUniqueValue, final AttributableUtils attrUtils) {
-
-        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
-        if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaName);
-            return null;
-        }
-        if (!schema.isUniqueConstraint()) {
-            LOG.error("This schema has not unique constraint: '{}'", schemaName);
-            return null;
-        }
-
-        List<? extends Subject<P, D, V>> result = findByAttrValue(schemaName, attrUniqueValue, attrUtils);
-        return result.isEmpty()
-                ? null
-                : result.iterator().next();
-    }
-
-    /**
-     * Find users / groups by derived attribute value. This method could fail if one or more string literals contained
-     * into the derived attribute value provided derive from identifier (schema name) replacement. When you are going to
-     * specify a derived attribute expression you must be quite sure that string literals used to build the expression
-     * cannot be found into the attribute values used to replace attribute schema names used as identifiers.
-     *
-     * @param schemaName derived schema name
-     * @param value derived attribute value
-     * @param attrUtils AttributableUtil
-     * @return list of users / groups
-     */
-    @Override
-    public List<? extends Subject<P, D, V>> findByDerAttrValue(
-            final String schemaName, final String value, final AttributableUtils attrUtils) {
-
-        DerSchema schema = derSchemaDAO.find(schemaName, attrUtils.derSchemaClass());
-        if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaName);
-            return Collections.<Subject<P, D, V>>emptyList();
-        }
-
-        // query string
-        final StringBuilder querystring = new StringBuilder();
-
-        boolean subquery = false;
-        for (String clause : getWhereClause(schema.getExpression(), value, attrUtils)) {
-            if (querystring.length() > 0) {
-                subquery = true;
-                querystring.append(" AND a.owner_id IN ( ");
-            }
-
-            querystring.append("SELECT a.owner_id ").
-                    append("FROM ").append(attrUtils.plainAttrClass().getSimpleName().substring(3)).append(" a, ").
-                    append(attrUtils.plainAttrValueClass().getSimpleName().substring(3)).append(" v, ").
-                    append(attrUtils.plainSchemaClass().getSimpleName().substring(3)).append(" s ").
-                    append("WHERE ").append(clause);
-
-            if (subquery) {
-                querystring.append(')');
-            }
-        }
-
-        LOG.debug("Execute query {}", querystring);
-
-        final Query query = entityManager.createNativeQuery(querystring.toString());
-
-        final List<Subject<P, D, V>> result = new ArrayList<>();
-        for (Object userId : query.getResultList()) {
-            Subject<P, D, V> subject = findInternal(Long.parseLong(userId.toString()));
-            if (!result.contains(subject)) {
-                result.add(subject);
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<? extends Subject<P, D, V>> findByResource(
-            final ExternalResource resource, final AttributableUtils attrUtils) {
-
-        Query query = entityManager.createQuery(
-                "SELECT e FROM " + attrUtils.attributableClass().getSimpleName() + " e "
-                + "WHERE :resource MEMBER OF e.resources");
-        query.setParameter("resource", resource);
-
-        return query.getResultList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..fd99019
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -0,0 +1,149 @@
+/*
+ * 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.dao;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+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;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObjectDAO {
+
+    @Override
+    protected AnyUtils init() {
+        return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.ANY_OBJECT);
+    }
+
+    @Override
+    protected void securityChecks(final AnyObject anyObject) {
+        Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_READ);
+        boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String realm) {
+                return anyObject.getRealm().getFullPath().startsWith(realm);
+            }
+        });
+        if (authRealms == null || authRealms.isEmpty() || !authorized) {
+            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+        }
+    }
+
+    @Override
+    public List<AnyObject> findByAnyType(final String anyTypeName) {
+        TypedQuery<AnyObject> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAAnyObject.class.getSimpleName() + " e WHERE e.type.name=:name", AnyObject.class);
+        query.setParameter("name", anyTypeName);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public void delete(final AnyObject any) {
+        for (Group group : findDynGroupMemberships(any)) {
+            group.getADynMembership().remove(any);
+        }
+
+        entityManager.remove(any);
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public List<Group> findDynGroupMemberships(final AnyObject anyObject) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
+                + " e WHERE :anyObject MEMBER OF e.members", Group.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public Collection<Group> findAllGroups(final AnyObject anyObject) {
+        return CollectionUtils.union(
+                CollectionUtils.collect(anyObject.getMemberships(), new Transformer<AMembership, Group>() {
+
+                    @Override
+                    public Group transform(final AMembership input) {
+                        return input.getRightEnd();
+                    }
+                }, new ArrayList<Group>()),
+                findDynGroupMemberships(anyObject));
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public Collection<Long> findAllGroupKeys(final AnyObject anyObject) {
+        return CollectionUtils.collect(findAllGroups(anyObject), new Transformer<Group, Long>() {
+
+            @Override
+            public Long transform(final Group input) {
+                return input.getKey();
+            }
+        });
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public Collection<ExternalResource> findAllResources(final AnyObject anyObject) {
+        Set<ExternalResource> result = new HashSet<>();
+        result.addAll(anyObject.getResources());
+        for (Group group : findAllGroups(anyObject)) {
+            result.addAll(group.getResources());
+        }
+
+        return result;
+    }
+
+    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+    @Override
+    public Collection<String> findAllResourceNames(final AnyObject anyObject) {
+        return CollectionUtils.collect(findAllResources(anyObject), new Transformer<ExternalResource, String>() {
+
+            @Override
+            public String transform(final ExternalResource input) {
+                return input.getKey();
+            }
+        });
+    }
+
+}


[26/29] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
index b74ec2b..fc48429 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
@@ -27,7 +27,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
 /**
@@ -39,32 +39,32 @@ public interface WorkflowService extends JAXRSService {
     /**
      * Exports workflow definition for matching kind.
      *
-     * @param kind user or group
+     * @param anyTypeKind any object type
      * @return workflow definition for matching kind
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response exportDefinition(@NotNull @PathParam("kind") SubjectType kind);
+    Response exportDefinition(@NotNull @PathParam("anyTypeKind") AnyTypeKind anyTypeKind);
 
     /**
      * Exports workflow diagram representation.
      *
-     * @param kind user or group
+     * @param anyTypeKind any object type
      * @return workflow diagram representation
      */
     @GET
     @Path("diagram.png")
     @Produces({ RESTHeaders.MEDIATYPE_IMAGE_PNG })
-    Response exportDiagram(@NotNull @PathParam("kind") SubjectType kind);
+    Response exportDiagram(@NotNull @PathParam("anyTypeKind") AnyTypeKind anyTypeKind);
 
     /**
      * Imports workflow definition for matching kind.
      *
-     * @param kind user or group
+     * @param anyTypeKind any object type
      * @param definition workflow definition for matching kind
      */
     @PUT
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void importDefinition(@NotNull @PathParam("kind") SubjectType kind, @NotNull String definition);
+    void importDefinition(@NotNull @PathParam("anyTypeKind") AnyTypeKind anyTypeKind, @NotNull String definition);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
new file mode 100644
index 0000000..7c998cf
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -0,0 +1,84 @@
+/*
+ * 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 java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+public abstract class AbstractAnyLogic<T extends AnyTO, V extends AnyMod>
+        extends AbstractResourceAssociator<T> {
+
+    private static class StartsWithPredicate implements Predicate<String> {
+
+        private final Collection<String> targets;
+
+        public StartsWithPredicate(final Collection<String> targets) {
+            this.targets = targets;
+        }
+
+        @Override
+        public boolean evaluate(final String realm) {
+            return CollectionUtils.exists(targets, new Predicate<String>() {
+
+                @Override
+                public boolean evaluate(final String target) {
+                    return realm.startsWith(target);
+                }
+            });
+        }
+
+    }
+
+    protected Set<String> getEffectiveRealms(
+            final Set<String> allowedRealms, final Collection<String> requestedRealms) {
+
+        final Set<String> allowed = RealmUtils.normalize(allowedRealms);
+        final Set<String> requested = RealmUtils.normalize(requestedRealms);
+
+        Set<String> effective = new HashSet<>();
+        CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
+        CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
+
+        return effective;
+    }
+
+    public abstract T read(Long key);
+
+    public abstract int count(List<String> realms);
+
+    public abstract T update(V attributableMod);
+
+    public abstract T delete(Long key);
+
+    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
+
+    public abstract List<T> search(
+            SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy, List<String> realms);
+
+    public abstract int searchCount(SearchCond searchCondition, List<String> realms);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
index 3d3b393..6741a89 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractResourceAssociator.java
@@ -19,9 +19,9 @@
 package org.apache.syncope.core.logic;
 
 import java.util.Collection;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 
-public abstract class AbstractResourceAssociator<T extends AbstractAttributableTO> extends AbstractLogic<T> {
+public abstract class AbstractResourceAssociator<T extends AnyTO> extends AbstractLogic<T> {
 
     public abstract T unlink(Long id, Collection<String> resources);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
deleted file mode 100644
index 4dcb324..0000000
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
+++ /dev/null
@@ -1,84 +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.logic;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.core.misc.RealmUtils;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-
-public abstract class AbstractSubjectLogic<T extends AbstractSubjectTO, V extends AbstractSubjectMod>
-        extends AbstractResourceAssociator<T> {
-
-    private static class StartsWithPredicate implements Predicate<String> {
-
-        private final Collection<String> targets;
-
-        public StartsWithPredicate(final Collection<String> targets) {
-            this.targets = targets;
-        }
-
-        @Override
-        public boolean evaluate(final String realm) {
-            return CollectionUtils.exists(targets, new Predicate<String>() {
-
-                @Override
-                public boolean evaluate(final String target) {
-                    return realm.startsWith(target);
-                }
-            });
-        }
-
-    }
-
-    protected Set<String> getEffectiveRealms(
-            final Set<String> allowedRealms, final Collection<String> requestedRealms) {
-
-        final Set<String> allowed = RealmUtils.normalize(allowedRealms);
-        final Set<String> requested = RealmUtils.normalize(requestedRealms);
-
-        Set<String> effective = new HashSet<>();
-        CollectionUtils.select(requested, new StartsWithPredicate(allowed), effective);
-        CollectionUtils.select(allowed, new StartsWithPredicate(requested), effective);
-
-        return effective;
-    }
-
-    public abstract T read(Long key);
-
-    public abstract int count(List<String> realms);
-
-    public abstract T update(V attributableMod);
-
-    public abstract T delete(Long key);
-
-    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
-
-    public abstract List<T> search(
-            SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy, List<String> realms);
-
-    public abstract int searchCount(SearchCond searchCondition, List<String> realms);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
new file mode 100644
index 0000000..5b186b5
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -0,0 +1,326 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
+ * Spring's Transactional logic at class level.
+ */
+@Component
+public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod> {
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    protected AnySearchDAO searchDAO;
+
+    @Autowired
+    protected AnyObjectDataBinder binder;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyTransformer attrTransformer;
+
+    @Resource(name = "anonymousUser")
+    protected String anonymousUser;
+
+    @Autowired
+    protected AnyObjectProvisioningManager provisioningManager;
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_READ + "')")
+    @Transactional(readOnly = true)
+    @Override
+    public AnyObjectTO read(final Long anyObjectKey) {
+        return binder.getAnyObjectTO(anyObjectKey);
+    }
+
+    @PreAuthorize("isAuthenticated()")
+    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Override
+    public int count(final List<String> realms) {
+        return anyObjectDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_LIST + "')")
+    @Transactional(readOnly = true)
+    @Override
+    public List<AnyObjectTO> list(
+            final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
+
+        return CollectionUtils.collect(anyObjectDAO.findAll(
+                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms),
+                page, size, orderBy),
+                new Transformer<AnyObject, AnyObjectTO>() {
+
+                    @Override
+                    public AnyObjectTO transform(final AnyObject input) {
+                        return binder.getAnyObjectTO(input);
+                    }
+                }, new ArrayList<AnyObjectTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
+    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Override
+    public int searchCount(final SearchCond searchCondition, final List<String> realms) {
+        return searchDAO.count(
+                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_SEARCH), realms),
+                searchCondition, AnyTypeKind.ANY_OBJECT);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
+    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Override
+    public List<AnyObjectTO> search(final SearchCond searchCondition, final int page, final int size,
+            final List<OrderByClause> orderBy, final List<String> realms) {
+
+        final List<AnyObject> matchingAnyObjects = searchDAO.search(
+                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_SEARCH), realms),
+                searchCondition, page, size, orderBy, AnyTypeKind.ANY_OBJECT);
+        return CollectionUtils.collect(matchingAnyObjects, new Transformer<AnyObject, AnyObjectTO>() {
+
+            @Override
+            public AnyObjectTO transform(final AnyObject input) {
+                return binder.getAnyObjectTO(input);
+            }
+        }, new ArrayList<AnyObjectTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_CREATE + "')")
+    public AnyObjectTO create(final AnyObjectTO anyObjectTO) {
+        if (anyObjectTO.getRealm() == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            throw sce;
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_CREATE),
+                Collections.singleton(anyObjectTO.getRealm()));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, null);
+        }
+
+        // Attributable transformation (if configured)
+        AnyObjectTO actual = attrTransformer.transform(anyObjectTO);
+        LOG.debug("Transformed: {}", actual);
+
+        /*
+         * Actual operations: workflow, propagation
+         */
+        Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(anyObjectTO);
+        AnyObjectTO savedTO = binder.getAnyObjectTO(created.getKey());
+        savedTO.getPropagationStatusTOs().addAll(created.getValue());
+        return savedTO;
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Override
+    public AnyObjectTO update(final AnyObjectMod anyObjectMod) {
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectMod.getKey());
+        if (anyObject == null) {
+            throw new NotFoundException("AnyObject with key " + anyObjectMod.getKey());
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObjectMod.getRealm()));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+        }
+
+        // Attribute value transformation (if configured)
+        AnyObjectMod actual = attrTransformer.transform(anyObjectMod);
+        LOG.debug("Transformed: {}", actual);
+
+        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(anyObjectMod);
+
+        AnyObjectTO updatedTO = binder.getAnyObjectTO(updated.getKey());
+        updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
+        return updatedTO;
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_DELETE + "')")
+    @Override
+    public AnyObjectTO delete(final Long anyObjectKey) {
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        if (anyObject == null) {
+            throw new NotFoundException("AnyObject with key " + anyObjectKey);
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
+                Collections.singleton(anyObject.getRealm().getFullPath()));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
+        }
+
+        List<PropagationStatus> statuses = provisioningManager.delete(anyObjectKey);
+
+        AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setKey(anyObjectKey);
+
+        anyObjectTO.getPropagationStatusTOs().addAll(statuses);
+
+        return anyObjectTO;
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) {
+        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.getResourcesToRemove().addAll(resources);
+        final Long updatedResult = provisioningManager.unlink(anyObjectMod);
+
+        return binder.getAnyObjectTO(updatedResult);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) {
+        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.getResourcesToAdd().addAll(resources);
+        return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) {
+        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(anyObjectKey);
+        anyObjectMod.getResourcesToRemove().addAll(resources);
+        return update(anyObjectMod);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO assign(
+            final Long anyObjectKey, final Collection<String> resources, final boolean changePwd, final String password) {
+
+        final AnyObjectMod userMod = new AnyObjectMod();
+        userMod.setKey(anyObjectKey);
+        userMod.getResourcesToAdd().addAll(resources);
+        return update(userMod);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO deprovision(final Long anyObjectKey, final Collection<String> resources) {
+        final AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+
+        List<PropagationStatus> statuses = provisioningManager.deprovision(anyObjectKey, resources);
+
+        AnyObjectTO updatedTO = binder.getAnyObjectTO(anyObject);
+        updatedTO.getPropagationStatusTOs().addAll(statuses);
+        return updatedTO;
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
+    @Transactional(rollbackFor = { Throwable.class })
+    @Override
+    public AnyObjectTO provision(
+            final Long anyObjectKey, final Collection<String> resources, final boolean changePwd, final String password) {
+        AnyObjectTO original = binder.getAnyObjectTO(anyObjectKey);
+
+        //trick: assign and retrieve propagation statuses ...
+        original.getPropagationStatusTOs().addAll(
+                assign(anyObjectKey, resources, changePwd, password).getPropagationStatusTOs());
+
+        // .... rollback.
+        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
+        return original;
+    }
+
+    @Override
+    protected AnyObjectTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException {
+        Long key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof Long) {
+                    key = (Long) args[i];
+                } else if (args[i] instanceof AnyObjectTO) {
+                    key = ((AnyObjectTO) args[i]).getKey();
+                } else if (args[i] instanceof AnyObjectMod) {
+                    key = ((AnyObjectMod) args[i]).getKey();
+                }
+            }
+        }
+
+        if ((key != null) && !key.equals(0L)) {
+            try {
+                return binder.getAnyObjectTO(key);
+            } catch (Throwable ignore) {
+                LOG.debug("Unresolved reference", ignore);
+                throw new UnresolvedReferenceException(ignore);
+            }
+        }
+
+        throw new UnresolvedReferenceException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
index ef95aaa..7d28c88 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
@@ -27,8 +27,8 @@ import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
 import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
@@ -74,7 +74,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
 
         CPlainAttr conf = confDAO.find(key);
         if (conf == null) {
-            CPlainSchema schema = plainSchemaDAO.find(key, CPlainSchema.class);
+            PlainSchema schema = plainSchemaDAO.find(key);
             if (schema == null) {
                 throw new NotFoundException("Configuration key " + key);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index eac9fde..793686f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -25,6 +25,8 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.PredicateUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
@@ -34,13 +36,12 @@ import org.apache.syncope.common.lib.to.ConnBundleTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.CollectionUtils2;
 import org.apache.syncope.common.lib.types.Entitlement;
 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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
@@ -138,20 +139,21 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
             CurrentLocale.set(new Locale(lang));
         }
 
-        return CollectionUtils2.collect(connInstanceDAO.findAll(), new Transformer<ConnInstance, ConnInstanceTO>() {
-
-            @Override
-            public ConnInstanceTO transform(final ConnInstance input) {
-                ConnInstanceTO result = null;
-                try {
-                    result = binder.getConnInstanceTO(input);
-                } catch (NotFoundException e) {
-                    LOG.error("Connector '{}#{}' not found", input.getBundleName(), input.getVersion());
-                }
-
-                return result;
-            }
-        }, PredicateUtils.notNullPredicate(), new ArrayList<ConnInstanceTO>());
+        return CollectionUtils.collect(IteratorUtils.filteredIterator(connInstanceDAO.findAll().iterator(),
+                PredicateUtils.notNullPredicate()), new Transformer<ConnInstance, ConnInstanceTO>() {
+
+                    @Override
+                    public ConnInstanceTO transform(final ConnInstance input) {
+                        ConnInstanceTO result = null;
+                        try {
+                            result = binder.getConnInstanceTO(input);
+                        } catch (NotFoundException e) {
+                            LOG.error("Connector '{}#{}' not found", input.getBundleName(), input.getVersion());
+                        }
+
+                        return result;
+                    }
+                }, new ArrayList<ConnInstanceTO>());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.CONNECTOR_READ + "')")

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index a3a3ab8..7129b74 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -34,24 +34,24 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.misc.RealmUtils;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 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.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -63,7 +63,7 @@ import org.springframework.transaction.interceptor.TransactionInterceptor;
  * Spring's Transactional logic at class level.
  */
 @Component
-public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
+public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
 
     @Autowired
     protected GroupDAO groupDAO;
@@ -72,7 +72,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     protected UserDAO userDAO;
 
     @Autowired
-    protected SubjectSearchDAO searchDAO;
+    protected AnySearchDAO searchDAO;
 
     @Autowired
     protected GroupDataBinder binder;
@@ -84,7 +84,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     protected PropagationTaskExecutor taskExecutor;
 
     @Autowired
-    protected AttributableTransformer attrTransformer;
+    protected AnyTransformer attrTransformer;
 
     @Resource(name = "anonymousUser")
     protected String anonymousUser;
@@ -144,7 +144,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
                 getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_SEARCH), realms),
-                searchCondition, SubjectType.GROUP);
+                searchCondition, AnyTypeKind.GROUP);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_SEARCH + "')")
@@ -155,7 +155,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
 
         final List<Group> matchingGroups = searchDAO.search(
                 getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_SEARCH), realms),
-                searchCondition, page, size, orderBy, SubjectType.GROUP);
+                searchCondition, page, size, orderBy, AnyTypeKind.GROUP);
         return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
 
             @Override
@@ -175,7 +175,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_CREATE),
                 Collections.singleton(groupTO.getRealm()));
         if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(SubjectType.GROUP, null);
+            throw new UnauthorizedException(AnyTypeKind.GROUP, null);
         }
 
         // Attributable transformation (if configured)
@@ -194,7 +194,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
     @Override
     public GroupTO update(final GroupMod groupMod) {
-        Group group = groupDAO.authFetch(groupMod.getKey());
+        Group group = groupDAO.authFind(groupMod.getKey());
         if (group == null) {
             throw new NotFoundException("Group with key " + groupMod.getKey());
         }
@@ -202,7 +202,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
                 Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
         if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(SubjectType.GROUP, group.getKey());
+            throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
         }
 
         // Attribute value transformation (if configured)
@@ -219,7 +219,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('" + Entitlement.GROUP_DELETE + "')")
     @Override
     public GroupTO delete(final Long groupKey) {
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
         if (group == null) {
             throw new NotFoundException("Group with key " + groupKey);
         }
@@ -227,7 +227,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
                 AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_DELETE),
                 Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
         if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(SubjectType.GROUP, group.getKey());
+            throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
         }
 
         List<Group> ownedGroups = groupDAO.findOwnedByGroup(groupKey);
@@ -301,7 +301,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO deprovision(final Long groupKey, final Collection<String> resources) {
-        final Group group = groupDAO.authFetch(groupKey);
+        final Group group = groupDAO.authFind(groupKey);
 
         List<PropagationStatus> statuses = provisioningManager.deprovision(groupKey, resources);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index d035301..4b5aac8 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -25,6 +25,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.PredicateUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.logging.log4j.Level;
@@ -35,7 +36,6 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.EventCategoryTO;
 import org.apache.syncope.common.lib.to.LoggerTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
 import org.apache.syncope.common.lib.types.AuditLoggerName;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -45,14 +45,14 @@ import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.common.lib.CollectionUtils2;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
@@ -106,20 +106,22 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
     @PreAuthorize("hasRole('" + Entitlement.AUDIT_LIST + "')")
     @Transactional(readOnly = true)
     public List<AuditLoggerName> listAudits() {
-        return CollectionUtils2.collect(list(LoggerType.AUDIT), new Transformer<LoggerTO, AuditLoggerName>() {
-
-            @Override
-            public AuditLoggerName transform(final LoggerTO logger) {
-                AuditLoggerName result = null;
-                try {
-                    result = AuditLoggerName.fromLoggerName(logger.getKey());
-                } catch (Exception e) {
-                    LOG.warn("Unexpected audit logger name: {}", logger.getKey(), e);
-                }
+        return CollectionUtils.collect(
+                IteratorUtils.filteredIterator(list(LoggerType.AUDIT).iterator(), PredicateUtils.notNullPredicate()),
+                new Transformer<LoggerTO, AuditLoggerName>() {
+
+                    @Override
+                    public AuditLoggerName transform(final LoggerTO logger) {
+                        AuditLoggerName result = null;
+                        try {
+                            result = AuditLoggerName.fromLoggerName(logger.getKey());
+                        } catch (Exception e) {
+                            LOG.warn("Unexpected audit logger name: {}", logger.getKey(), e);
+                        }
 
-                return result;
-            }
-        }, PredicateUtils.notNullPredicate(), new ArrayList<AuditLoggerName>());
+                        return result;
+                    }
+                }, new ArrayList<AuditLoggerName>());
     }
 
     private void throwInvalidLogger(final LoggerType type) {
@@ -263,17 +265,17 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             events.add(new EventCategoryTO(EventCategoryType.SYNCHRONIZATION));
             events.add(new EventCategoryTO(EventCategoryType.PUSH));
 
-            for (AttributableType attributableType : AttributableType.values()) {
+            for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
                 for (ExternalResource resource : resourceDAO.findAll()) {
                     EventCategoryTO propEventCategoryTO = new EventCategoryTO(EventCategoryType.PROPAGATION);
                     EventCategoryTO syncEventCategoryTO = new EventCategoryTO(EventCategoryType.SYNCHRONIZATION);
                     EventCategoryTO pushEventCategoryTO = new EventCategoryTO(EventCategoryType.PUSH);
 
-                    propEventCategoryTO.setCategory(attributableType.name().toLowerCase());
+                    propEventCategoryTO.setCategory(anyTypeKind.name().toLowerCase());
                     propEventCategoryTO.setSubcategory(resource.getKey());
 
-                    syncEventCategoryTO.setCategory(attributableType.name().toLowerCase());
-                    pushEventCategoryTO.setCategory(attributableType.name().toLowerCase());
+                    syncEventCategoryTO.setCategory(anyTypeKind.name().toLowerCase());
+                    pushEventCategoryTO.setCategory(anyTypeKind.name().toLowerCase());
                     syncEventCategoryTO.setSubcategory(resource.getKey());
                     pushEventCategoryTO.setSubcategory(resource.getKey());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
index 4c3230c..d8611ad 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
@@ -37,6 +37,7 @@ import org.apache.cocoon.sax.component.XMLGenerator;
 import org.apache.cocoon.sax.component.XMLSerializer;
 import org.apache.cocoon.sax.component.XSLTTransformer;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.PredicateUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.io.IOUtils;
@@ -62,7 +63,6 @@ import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.core.logic.report.Reportlet;
 import org.apache.syncope.core.logic.report.ReportletConfClass;
 import org.apache.syncope.core.logic.report.TextSerializer;
-import org.apache.syncope.common.lib.CollectionUtils2;
 import org.apache.syncope.common.lib.to.AbstractExecTO;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.JobAction;
@@ -169,7 +169,9 @@ public class ReportLogic extends AbstractJobLogic<ReportTO> {
 
     @SuppressWarnings({ "rawtypes" })
     private Set<Class<Reportlet>> getAllReportletClasses() {
-        return CollectionUtils2.collect(classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET),
+        return CollectionUtils.collect(IteratorUtils.filteredIterator(
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET).iterator(),
+                PredicateUtils.notNullPredicate()),
                 new Transformer<String, Class<Reportlet>>() {
 
                     @SuppressWarnings("unchecked")
@@ -187,13 +189,14 @@ public class ReportLogic extends AbstractJobLogic<ReportTO> {
 
                         return result;
                     }
-                },
-                PredicateUtils.notNullPredicate(), new HashSet<Class<Reportlet>>());
+                }, new HashSet<Class<Reportlet>>());
     }
 
     @PreAuthorize("hasRole('" + Entitlement.REPORT_LIST + "')")
+    @SuppressWarnings({ "rawtypes" })
     public Set<String> getReportletConfClasses() {
-        return CollectionUtils2.collect(getAllReportletClasses(),
+        return CollectionUtils.collect(IteratorUtils.filteredIterator(getAllReportletClasses().iterator(),
+                PredicateUtils.notNullPredicate()),
                 new Transformer<Class<Reportlet>, String>() {
 
                     @Override
@@ -201,7 +204,7 @@ public class ReportLogic extends AbstractJobLogic<ReportTO> {
                         Class<? extends ReportletConf> reportletConfClass = getReportletConfClass(reportletClass);
                         return reportletConfClass == null ? null : reportletConfClass.getName();
                     }
-                }, PredicateUtils.notNullPredicate(), new HashSet<String>());
+                }, new HashSet<String>());
     }
 
     public Class<Reportlet> findReportletClassHavingConfClass(final Class<? extends ReportletConf> reportletConfClass) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 4d31e8d..073150b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -29,31 +29,34 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
+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.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+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.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.identityconnectors.framework.common.objects.Uid;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -67,6 +70,12 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -82,7 +91,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private ConnectorFactory connFactory;
 
     @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
+    private AnyUtilsFactory anyUtilsFactory;
 
     @PreAuthorize("hasRole('" + Entitlement.RESOURCE_CREATE + "')")
     public ResourceTO create(final ResourceTO resourceTO) {
@@ -170,37 +179,45 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
     @PreAuthorize("hasRole('" + Entitlement.RESOURCE_GETCONNECTOROBJECT + "')")
     @Transactional(readOnly = true)
-    public ConnObjectTO getConnectorObject(final String resourceName, final SubjectType type, final Long id) {
-        ExternalResource resource = resourceDAO.find(resourceName);
+    public ConnObjectTO readConnObject(final String resourceKey, final String anyTypeKey, final Long key) {
+        ExternalResource resource = resourceDAO.find(resourceKey);
         if (resource == null) {
-            throw new NotFoundException("Resource '" + resourceName + "'");
+            throw new NotFoundException("Resource '" + resourceKey + "'");
+        }
+        AnyType anyType = anyTypeDAO.find(anyTypeKey);
+        if (anyType == null) {
+            throw new NotFoundException("AnyType '" + anyTypeKey + "'");
+        }
+        Provision provision = resource.getProvision(anyType);
+        if (provision == null) {
+            throw new NotFoundException("Provision on resource '" + resourceKey + "' for type '" + anyTypeKey + "'");
         }
 
-        Subject<?, ?, ?> subject = type == SubjectType.USER
-                ? userDAO.find(id)
-                : groupDAO.find(id);
-        if (subject == null) {
-            throw new NotFoundException(type + " " + id);
+        Any<?, ?, ?> any = anyType.getKind() == AnyTypeKind.USER
+                ? userDAO.find(key)
+                : anyType.getKind() == AnyTypeKind.ANY_OBJECT
+                        ? anyObjectDAO.find(key)
+                        : groupDAO.find(key);
+        if (any == null) {
+            throw new NotFoundException(anyType + " " + key);
         }
 
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType());
+        AnyUtils attrUtils = anyUtilsFactory.getInstance(anyType.getKind());
 
-        MappingItem accountIdItem = attrUtils.getAccountIdItem(resource);
-        if (accountIdItem == null) {
+        MappingItem connObjectKeyItem = attrUtils.getConnObjectKeyItem(provision);
+        if (connObjectKeyItem == null) {
             throw new NotFoundException(
-                    "AccountId mapping for " + type + " " + id + " on resource '" + resourceName + "'");
+                    "ConnObjectKey mapping for " + anyType + " " + key + " on resource '" + resourceKey + "'");
         }
-        final String accountIdValue = MappingUtils.getAccountIdValue(
-                subject, resource, attrUtils.getAccountIdItem(resource));
+        String connObjectKeyValue = MappingUtils.getConnObjectKeyValue(any, provision);
 
-        final ObjectClass objectClass = SubjectType.USER == type ? ObjectClass.ACCOUNT : ObjectClass.GROUP;
-
-        final Connector connector = connFactory.getConnector(resource);
-        final ConnectorObject connectorObject = connector.getObject(objectClass, new Uid(accountIdValue),
-                connector.getOperationOptions(attrUtils.getMappingItems(resource, MappingPurpose.BOTH)));
+        Connector connector = connFactory.getConnector(resource);
+        ConnectorObject connectorObject = connector.getObject(
+                provision.getObjectClass(), new Uid(connObjectKeyValue),
+                connector.getOperationOptions(attrUtils.getMappingItems(provision, MappingPurpose.BOTH)));
         if (connectorObject == null) {
-            throw new NotFoundException("Object " + accountIdValue + " with class " + objectClass
-                    + "not found on resource " + resourceName);
+            throw new NotFoundException("Object " + connObjectKeyValue + " with class " + provision.getObjectClass()
+                    + "not found on resource " + resourceKey);
         }
 
         final Set<Attribute> attributes = connectorObject.getAttributes();
@@ -217,9 +234,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     @PreAuthorize("hasRole('" + Entitlement.CONNECTOR_READ + "')")
     @Transactional(readOnly = true)
     public boolean check(final ResourceTO resourceTO) {
-        final ConnInstance connInstance = binder.getConnInstance(resourceTO);
-
-        final Connector connector = connFactory.createConnector(connInstance, connInstance.getConfiguration());
+        ConnInstance connInstance = binder.getConnInstance(resourceTO);
+        Connector connector = connFactory.createConnector(connInstance, connInstance.getConfiguration());
 
         boolean result;
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index a9c509c..befa8bf 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -30,7 +30,6 @@ import org.apache.syncope.common.lib.to.AbstractSchemaTO;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.common.lib.types.AttributableType;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -39,9 +38,8 @@ import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
@@ -65,22 +63,22 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
     private SchemaDataBinder binder;
 
     @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
+    private EntityFactory entityFactory;
 
-    private boolean doesSchemaExist(final SchemaType schemaType, final String name, final AttributableUtils attrUtils) {
+    private boolean doesSchemaExist(final SchemaType schemaType, final String name) {
         boolean found;
 
         switch (schemaType) {
             case VIRTUAL:
-                found = virSchemaDAO.find(name, attrUtils.virSchemaClass()) != null;
+                found = virSchemaDAO.find(name) != null;
                 break;
 
             case DERIVED:
-                found = derSchemaDAO.find(name, attrUtils.derSchemaClass()) != null;
+                found = derSchemaDAO.find(name) != null;
                 break;
 
             case PLAIN:
-                found = plainSchemaDAO.find(name, attrUtils.plainSchemaClass()) != null;
+                found = plainSchemaDAO.find(name) != null;
                 break;
 
             default:
@@ -92,30 +90,28 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
     @PreAuthorize("hasRole('" + Entitlement.SCHEMA_CREATE + "')")
     @SuppressWarnings("unchecked")
-    public <T extends AbstractSchemaTO> T create(
-            final AttributableType attrType, final SchemaType schemaType, final T schemaTO) {
-
+    public <T extends AbstractSchemaTO> T create(final SchemaType schemaType, final T schemaTO) {
         if (StringUtils.isBlank(schemaTO.getKey())) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
             sce.getElements().add("Schema name");
             throw sce;
         }
 
-        AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
-        if (doesSchemaExist(schemaType, schemaTO.getKey(), attrUtils)) {
-            throw new DuplicateException(attrType + "/" + schemaType + "/" + schemaTO.getKey());
+        if (doesSchemaExist(schemaType, schemaTO.getKey())) {
+            throw new DuplicateException(schemaType + "/" + schemaTO.getKey());
         }
 
         T created;
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = attrUtils.newVirSchema();
+                VirSchema virSchema = entityFactory.newEntity(VirSchema.class);
                 binder.create((VirSchemaTO) schemaTO, virSchema);
                 virSchema = virSchemaDAO.save(virSchema);
                 created = (T) binder.getVirSchemaTO(virSchema);
                 break;
+
             case DERIVED:
-                DerSchema derSchema = attrUtils.newDerSchema();
+                DerSchema derSchema = entityFactory.newEntity(DerSchema.class);
                 binder.create((DerSchemaTO) schemaTO, derSchema);
                 derSchema = derSchemaDAO.save(derSchema);
 
@@ -124,47 +120,43 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema normalSchema = attrUtils.newPlainSchema();
+                PlainSchema normalSchema = entityFactory.newEntity(PlainSchema.class);
                 binder.create((PlainSchemaTO) schemaTO, normalSchema);
                 normalSchema = plainSchemaDAO.save(normalSchema);
 
-                created = (T) binder.getPlainSchemaTO(normalSchema, attrUtils);
+                created = (T) binder.getPlainSchemaTO(normalSchema);
         }
         return created;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.SCHEMA_DELETE + "')")
-    public void delete(final AttributableType attrType, final SchemaType schemaType, final String schemaName) {
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
-
-        if (!doesSchemaExist(schemaType, schemaName, attrUtils)) {
-            throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaName);
+    public void delete(final SchemaType schemaType, final String schemaName) {
+        if (!doesSchemaExist(schemaType, schemaName)) {
+            throw new NotFoundException(schemaType + "/" + schemaName);
         }
 
         switch (schemaType) {
             case VIRTUAL:
-                virSchemaDAO.delete(schemaName, attrUtils);
+                virSchemaDAO.delete(schemaName);
                 break;
 
             case DERIVED:
-                derSchemaDAO.delete(schemaName, attrUtils);
+                derSchemaDAO.delete(schemaName);
                 break;
 
             case PLAIN:
             default:
-                plainSchemaDAO.delete(schemaName, attrUtils);
+                plainSchemaDAO.delete(schemaName);
         }
     }
 
     @PreAuthorize("isAuthenticated()")
     @SuppressWarnings("unchecked")
-    public <T extends AbstractSchemaTO> List<T> list(final AttributableType attrType, final SchemaType schemaType) {
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
-
+    public <T extends AbstractSchemaTO> List<T> list(final SchemaType schemaType) {
         List<T> result;
         switch (schemaType) {
             case VIRTUAL:
-                result = CollectionUtils.collect(virSchemaDAO.findAll(attrUtils.virSchemaClass()),
+                result = CollectionUtils.collect(virSchemaDAO.findAll(),
                         new Transformer<VirSchema, T>() {
 
                             @Override
@@ -175,7 +167,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                result = CollectionUtils.collect(derSchemaDAO.findAll(attrUtils.derSchemaClass()),
+                result = CollectionUtils.collect(derSchemaDAO.findAll(),
                         new Transformer<DerSchema, T>() {
 
                             @Override
@@ -187,12 +179,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                result = CollectionUtils.collect(plainSchemaDAO.findAll(attrUtils.plainSchemaClass()),
+                result = CollectionUtils.collect(plainSchemaDAO.findAll(),
                         new Transformer<PlainSchema, T>() {
 
                             @Override
                             public T transform(final PlainSchema input) {
-                                return (T) binder.getPlainSchemaTO(input, attrUtils);
+                                return (T) binder.getPlainSchemaTO(input);
                             }
                         }, new ArrayList<T>());
         }
@@ -202,15 +194,11 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
     @PreAuthorize("hasRole('" + Entitlement.SCHEMA_READ + "')")
     @SuppressWarnings("unchecked")
-    public <T extends AbstractSchemaTO> T read(
-            final AttributableType attrType, final SchemaType schemaType, final String schemaName) {
-
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
-
+    public <T extends AbstractSchemaTO> T read(final SchemaType schemaType, final String schemaName) {
         T read;
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = virSchemaDAO.find(schemaName, attrUtils.virSchemaClass());
+                VirSchema virSchema = virSchemaDAO.find(schemaName);
                 if (virSchema == null) {
                     throw new NotFoundException("Virtual Schema '" + schemaName + "'");
                 }
@@ -219,7 +207,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                DerSchema derSchema = derSchemaDAO.find(schemaName, attrUtils.derSchemaClass());
+                DerSchema derSchema = derSchemaDAO.find(schemaName);
                 if (derSchema == null) {
                     throw new NotFoundException("Derived schema '" + schemaName + "'");
                 }
@@ -229,30 +217,26 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(schemaName);
                 if (schema == null) {
                     throw new NotFoundException("Schema '" + schemaName + "'");
                 }
 
-                read = (T) binder.getPlainSchemaTO(schema, attrUtils);
+                read = (T) binder.getPlainSchemaTO(schema);
         }
 
         return read;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.SCHEMA_UPDATE + "')")
-    public <T extends AbstractSchemaTO> void update(
-            final AttributableType attrType, final SchemaType schemaType, final T schemaTO) {
-
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
-
-        if (!doesSchemaExist(schemaType, schemaTO.getKey(), attrUtils)) {
-            throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaTO.getKey());
+    public <T extends AbstractSchemaTO> void update(final SchemaType schemaType, final T schemaTO) {
+        if (!doesSchemaExist(schemaType, schemaTO.getKey())) {
+            throw new NotFoundException(schemaType + "/" + schemaTO.getKey());
         }
 
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = virSchemaDAO.find(schemaTO.getKey(), attrUtils.virSchemaClass());
+                VirSchema virSchema = virSchemaDAO.find(schemaTO.getKey());
                 if (virSchema == null) {
                     throw new NotFoundException("Virtual Schema '" + schemaTO.getKey() + "'");
                 }
@@ -262,7 +246,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                DerSchema derSchema = derSchemaDAO.find(schemaTO.getKey(), attrUtils.derSchemaClass());
+                DerSchema derSchema = derSchemaDAO.find(schemaTO.getKey());
                 if (derSchema == null) {
                     throw new NotFoundException("Derived schema '" + schemaTO.getKey() + "'");
                 }
@@ -273,12 +257,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey(), attrUtils.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey());
                 if (schema == null) {
                     throw new NotFoundException("Schema '" + schemaTO.getKey() + "'");
                 }
 
-                binder.update((PlainSchemaTO) schemaTO, schema, attrUtils);
+                binder.update((PlainSchemaTO) schemaTO, schema);
                 plainSchemaDAO.save(schema);
         }
     }
@@ -305,15 +289,13 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
         if (key != null) {
             try {
-                final AttributableUtils attrUtils = attrUtilsFactory.getInstance(kind);
-
                 AbstractSchemaTO result = null;
 
-                PlainSchema plainSchema = plainSchemaDAO.find(key, attrUtils.plainSchemaClass());
+                PlainSchema plainSchema = plainSchemaDAO.find(key);
                 if (plainSchema == null) {
-                    DerSchema derSchema = derSchemaDAO.find(key, attrUtils.derSchemaClass());
+                    DerSchema derSchema = derSchemaDAO.find(key);
                     if (derSchema == null) {
-                        VirSchema virSchema = virSchemaDAO.find(key, attrUtils.virSchemaClass());
+                        VirSchema virSchema = virSchemaDAO.find(key);
                         if (virSchema != null) {
                             result = binder.getVirSchemaTO(virSchema);
                         }
@@ -321,7 +303,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                         result = binder.getDerSchemaTO(derSchema);
                     }
                 } else {
-                    result = binder.getPlainSchemaTO(plainSchema, attrUtils);
+                    result = binder.getPlainSchemaTO(plainSchema);
                 }
 
                 return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 72e03e5..bc8fb0f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -28,12 +28,14 @@ import org.apache.syncope.common.lib.to.SyncopeTO;
 import org.apache.syncope.core.logic.init.ImplementationClassNamesLoader;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.java.notification.NotificationManagerImpl;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.springframework.aop.support.AopUtils;
@@ -55,7 +57,10 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
     private ConnIdBundleManager bundleManager;
 
     @Autowired
-    private AttributableTransformer attrTransformer;
+    private AnyTransformer anyTransformer;
+
+    @Autowired
+    private AnyObjectWorkflowAdapter awfAdapter;
 
     @Autowired
     private UserWorkflowAdapter uwfAdapter;
@@ -64,6 +69,9 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
     private GroupWorkflowAdapter gwfAdapter;
 
     @Autowired
+    private AnyObjectProvisioningManager aProvisioningManager;
+
+    @Autowired
     private UserProvisioningManager uProvisioningManager;
 
     @Autowired
@@ -109,11 +117,13 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
             }
         }
 
-        syncopeTO.setAttributableTransformer(attrTransformer.getClass().getName());
+        syncopeTO.setAnyTransformer(anyTransformer.getClass().getName());
 
+        syncopeTO.setAnyObjectWorkflowAdapter(AopUtils.getTargetClass(awfAdapter).getName());
         syncopeTO.setUserWorkflowAdapter(AopUtils.getTargetClass(uwfAdapter).getName());
         syncopeTO.setGroupWorkflowAdapter(AopUtils.getTargetClass(gwfAdapter).getName());
 
+        syncopeTO.setAnyObjectProvisioningManager(aProvisioningManager.getClass().getName());
         syncopeTO.setUserProvisioningManager(uProvisioningManager.getClass().getName());
         syncopeTO.setGroupProvisioningManager(gProvisioningManager.getClass().getName());
         syncopeTO.setVirAttrCache(virAttrCache.getClass().getName());

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 53d974e..2ec1175 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -32,23 +32,20 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
 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.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -57,6 +54,8 @@ import org.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -68,7 +67,7 @@ import org.springframework.transaction.interceptor.TransactionInterceptor;
  * Spring's Transactional logic at class level.
  */
 @Component
-public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
+public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
 
     @Autowired
     protected UserDAO userDAO;
@@ -77,7 +76,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     protected GroupDAO groupDAO;
 
     @Autowired
-    protected SubjectSearchDAO searchDAO;
+    protected AnySearchDAO searchDAO;
 
     @Autowired
     protected UserDataBinder binder;
@@ -92,7 +91,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     protected PropagationTaskExecutor taskExecutor;
 
     @Autowired
-    protected AttributableTransformer attrTransformer;
+    protected AnyTransformer anyTransformer;
 
     @Autowired
     protected UserProvisioningManager provisioningManager;
@@ -157,7 +156,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
                 getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_SEARCH), realms),
-                searchCondition, SubjectType.USER);
+                searchCondition, AnyTypeKind.USER);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_SEARCH + "')")
@@ -168,7 +167,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
 
         List<User> matchingUsers = searchDAO.search(
                 getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.USER_SEARCH), realms),
-                searchCondition, page, size, orderBy, SubjectType.USER);
+                searchCondition, page, size, orderBy, AnyTypeKind.USER);
         return CollectionUtils.collect(matchingUsers, new Transformer<User, UserTO>() {
 
             @Override
@@ -193,7 +192,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
                 AuthContextUtils.getAuthorizations().get(Entitlement.USER_CREATE),
                 Collections.singleton(userTO.getRealm()));
         if (effectiveRealms.isEmpty()) {
-            throw new UnauthorizedException(SubjectType.USER, null);
+            throw new UnauthorizedException(AnyTypeKind.USER, null);
         }
 
         return doCreate(userTO, storePassword);
@@ -201,7 +200,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
 
     protected UserTO doCreate(final UserTO userTO, final boolean storePassword) {
         // Attributable transformation (if configured)
-        UserTO actual = attrTransformer.transform(userTO);
+        UserTO actual = anyTransformer.transform(userTO);
         LOG.debug("Transformed: {}", actual);
 
         Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(actual, storePassword);
@@ -226,25 +225,10 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     @Override
     public UserTO update(final UserMod userMod) {
         // AttributableMod transformation (if configured)
-        UserMod actual = attrTransformer.transform(userMod);
+        UserMod actual = anyTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
 
-        // SYNCOPE-501: check if there are memberships to be removed with virtual attributes assigned
-        boolean removeMemberships = false;
-        for (Long membershipId : actual.getMembershipsToRemove()) {
-            if (!virtAttrHandler.fillMembershipVirtual(
-                    null,
-                    null,
-                    membershipId,
-                    Collections.<String>emptySet(),
-                    Collections.<AttrMod>emptySet(),
-                    true).isEmpty()) {
-
-                removeMemberships = true;
-            }
-        }
-
-        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(actual, removeMemberships);
+        Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(actual);
 
         UserTO updatedTO = binder.getUserTO(updated.getKey());
         updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
@@ -277,7 +261,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Transactional(rollbackFor = { Throwable.class })
     public UserTO status(final StatusMod statusMod) {
-        User user = userDAO.authFetch(statusMod.getKey());
+        User user = userDAO.authFind(statusMod.getKey());
 
         Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(user, statusMod);
         final UserTO savedTO = binder.getUserTO(updated.getKey());
@@ -414,7 +398,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO deprovision(final Long key, final Collection<String> resources) {
-        final User user = userDAO.authFetch(key);
+        final User user = userDAO.authFind(key);
 
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
index d1a1657..51d8b45 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
@@ -22,7 +22,7 @@ import java.lang.reflect.Method;
 import java.util.List;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.to.WorkflowFormTO;
@@ -84,7 +84,7 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_FORM_READ + "') and hasRole('" + Entitlement.USER_READ + "')")
     @Transactional(rollbackFor = { Throwable.class })
     public WorkflowFormTO getFormForUser(final Long key) {
-        User user = userDAO.authFetch(key);
+        User user = userDAO.authFind(key);
         return uwfAdapter.getForm(user.getWorkflowId());
     }
 
@@ -97,14 +97,14 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_FORM_READ + "') and hasRole('" + Entitlement.USER_READ + "')")
     @Transactional(rollbackFor = { Throwable.class })
     public List<WorkflowFormTO> getForms(final Long key, final String formName) {
-        User user = userDAO.authFetch(key);
+        User user = userDAO.authFind(key);
         return uwfAdapter.getForms(user.getWorkflowId(), formName);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_FORM_SUBMIT + "')")
     @Transactional(rollbackFor = { Throwable.class })
     public UserTO submitForm(final WorkflowFormTO form) {
-        WorkflowResult<? extends AbstractAttributableMod> updated = uwfAdapter.submitForm(form);
+        WorkflowResult<? extends AnyMod> updated = uwfAdapter.submitForm(form);
 
         // propByRes can be made empty by the workflow definition if no propagation should occur 
         // (for example, with rejected users)

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/logic/src/main/java/org/apache/syncope/core/logic/WorkflowLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/WorkflowLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/WorkflowLogic.java
index 28ef901..58777f7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/WorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/WorkflowLogic.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import javax.ws.rs.core.MediaType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.WorkflowAdapter;
@@ -36,6 +37,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class WorkflowLogic extends AbstractTransactionalLogic<AbstractBaseBean> {
 
     @Autowired
+    private AnyObjectWorkflowAdapter awfAdapter;
+
+    @Autowired
     private UserWorkflowAdapter uwfAdapter;
 
     @Autowired
@@ -55,6 +59,12 @@ public class WorkflowLogic extends AbstractTransactionalLogic<AbstractBaseBean>
 
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_READ + "')")
     @Transactional(readOnly = true)
+    public void exportAnyObjectDefinition(final MediaType format, final OutputStream os) {
+        exportDefinition(awfAdapter, getFormat(format), os);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_READ + "')")
+    @Transactional(readOnly = true)
     public void exportUserDefinition(final MediaType format, final OutputStream os) {
         exportDefinition(uwfAdapter, getFormat(format), os);
     }
@@ -71,6 +81,12 @@ public class WorkflowLogic extends AbstractTransactionalLogic<AbstractBaseBean>
 
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_READ + "')")
     @Transactional(readOnly = true)
+    public void exportAnyObjectDiagram(final OutputStream os) {
+        exportDiagram(awfAdapter, os);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_READ + "')")
+    @Transactional(readOnly = true)
     public void exportUserDiagram(final OutputStream os) {
         exportDiagram(uwfAdapter, os);
     }
@@ -88,6 +104,11 @@ public class WorkflowLogic extends AbstractTransactionalLogic<AbstractBaseBean>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_UPDATE + "')")
+    public void importAnyObjectDefinition(final MediaType format, final String definition) {
+        importDefinition(awfAdapter, getFormat(format), definition);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.WORKFLOW_DEF_UPDATE + "')")
     public void importUserDefinition(final MediaType format, final String definition) {
         importDefinition(uwfAdapter, getFormat(format), definition);
     }